Compare commits
480 Commits
1.0.0-beta
...
setmessage
Author | SHA1 | Date | |
---|---|---|---|
|
d5d9ac5c76 | ||
|
9d4238e5cc | ||
|
ee6f6ae391 | ||
|
95a51aafdc | ||
|
5e7cd79ed9 | ||
|
aba6173e23 | ||
|
e2c3b35391 | ||
|
448de23f59 | ||
|
44a07c74fd | ||
|
0f8af4ba1c | ||
|
214d788029 | ||
|
530bf22bd5 | ||
|
ccc98370eb | ||
|
7640bc029c | ||
|
3f72eb51a0 | ||
|
8801ace247 | ||
|
faf46e4447 | ||
|
63978e226b | ||
|
b96164d4f5 | ||
|
944070dfb1 | ||
|
f0584df1d0 | ||
|
ba209c2bdd | ||
|
c6e2f28b97 | ||
|
2436bb0128 | ||
|
9c4640e010 | ||
|
1ee43113b1 | ||
|
902f477ee3 | ||
|
9c1d46ff92 | ||
|
9cbd0fceea | ||
|
b22a4f94ab | ||
|
a4c351fd4f | ||
|
a364d4950d | ||
|
7805974736 | ||
|
c1dae95f71 | ||
|
e7c2ff3bd2 | ||
|
25459b52a1 | ||
|
b81be8f358 | ||
|
aa6c0b9d6e | ||
|
64580237d5 | ||
|
b93165592e | ||
|
83c1e44925 | ||
|
3088115aba | ||
|
fc93e502b8 | ||
|
e90e6eaac3 | ||
|
2f4dcba54d | ||
|
683c6a748e | ||
|
175a871ee0 | ||
|
b4e2061e85 | ||
|
2aef99c440 | ||
|
6c125e125f | ||
|
88cbc32abc | ||
|
8f45e8f84a | ||
|
21635aadfe | ||
|
d5234888b3 | ||
|
1f5ff0c6d3 | ||
|
2a2541df59 | ||
|
cd629c1699 | ||
|
4d6828ec14 | ||
|
dae1d6057e | ||
|
6726c42cc8 | ||
|
4f6023e44c | ||
|
9e16d7f433 | ||
|
aa86cfc55f | ||
|
6931cb9895 | ||
|
d32d04bd4e | ||
|
0b3e9bf5e2 | ||
|
a4af7b8e21 | ||
|
72deee5d74 | ||
|
5e9e523d4c | ||
|
c54509df3d | ||
|
63cc9adeaa | ||
|
74d760a46d | ||
|
d46531def8 | ||
|
eb09ec6834 | ||
|
9bd9c6a400 | ||
|
7321e206c5 | ||
|
2c7917f0ca | ||
|
d94b20a908 | ||
|
b1b1fe21dd | ||
|
1db3af7c8e | ||
|
397fe31f97 | ||
|
bc283aa025 | ||
|
9dbdf0947b | ||
|
7c21bf4555 | ||
|
361dc194ee | ||
|
8c1aa83d12 | ||
|
d2755a8049 | ||
|
1b78bd1684 | ||
|
5f67f1f078 | ||
|
07061928df | ||
|
18ff2df65c | ||
|
7b1411d171 | ||
|
3a1d0f3695 | ||
|
2cd5e1d3c5 | ||
|
000765fb77 | ||
|
0ff324b0db | ||
|
a96d5096fe | ||
|
e8ef476a6d | ||
|
22b9df62d1 | ||
|
6026da867b | ||
|
4d58902ba7 | ||
|
4dc1343445 | ||
|
080487cb33 | ||
|
0febcf4f9e | ||
|
cd23f711ed | ||
|
f9b147af42 | ||
|
775f1110d3 | ||
|
57649a9b81 | ||
|
72a268b70a | ||
|
f86a171dff | ||
|
e022b782a9 | ||
|
bd67731bb7 | ||
|
25de4e4782 | ||
|
c590247afa | ||
|
5d36539271 | ||
|
0d673486a3 | ||
|
29f1651a18 | ||
|
dd20a3e685 | ||
|
75a5b1354c | ||
|
dae9ac8173 | ||
|
78b735276b | ||
|
e10dd54e2b | ||
|
cb8deab1f9 | ||
|
e5c27d0236 | ||
|
faf6fa9450 | ||
|
873bdc6733 | ||
|
8a40b075b5 | ||
|
56c41374bf | ||
|
a08c2c6437 | ||
|
e94634544c | ||
|
07fe5b247b | ||
|
c1c694035d | ||
|
147d2a02be | ||
|
6f91786f4d | ||
|
f62a933d1c | ||
|
451835fbeb | ||
|
547e7a1b21 | ||
|
053e3ba923 | ||
|
bf65dcd49b | ||
|
a1d186112a | ||
|
ca7a298509 | ||
|
ff4d58f648 | ||
|
a1e10e99fa | ||
|
16bda530f6 | ||
|
bf9e04d9db | ||
|
8df86a75b1 | ||
|
5056203023 | ||
|
a0026e66ce | ||
|
f75dd2209d | ||
|
e35f6d9e35 | ||
|
3cb00ce4e0 | ||
|
8e18cf5986 | ||
|
81f80600f5 | ||
|
895156675f | ||
|
1c424e2e0a | ||
|
0124bb17e8 | ||
|
2c89b2d262 | ||
|
c7bbe2f1fe | ||
|
88609a8829 | ||
|
329beb166c | ||
|
e36f3d937c | ||
|
1395092ca6 | ||
|
c09004dbc8 | ||
|
7efe4a2776 | ||
|
b763e0b0cb | ||
|
ddd0d1bef3 | ||
|
dbca2178c0 | ||
|
af742ea536 | ||
|
14c1a86b9b | ||
|
ee3dc8c4cd | ||
|
1ed148aaf5 | ||
|
3327adb1ae | ||
|
4d5f771f9f | ||
|
aa69d663ed | ||
|
29d1894f9a | ||
|
e5738d608c | ||
|
9775d3a33d | ||
|
ad4cf8d631 | ||
|
a27e8777aa | ||
|
d23edcc0b5 | ||
|
52373e5bef | ||
|
bb70e796a1 | ||
|
3365d26b40 | ||
|
d3c111b533 | ||
|
ec876eb102 | ||
|
dddfb1ec08 | ||
|
6fc9c03d70 | ||
|
199ff071e8 | ||
|
7e4a06044a | ||
|
d047b75cb7 | ||
|
6fb6b13037 | ||
|
460c5a1ae3 | ||
|
9955bcc339 | ||
|
0a3ab996eb | ||
|
46f912a6f9 | ||
|
01e0f24752 | ||
|
7178c63e10 | ||
|
30c402eb83 | ||
|
2601cc898c | ||
|
d2a8823808 | ||
|
6b61fa9f6f | ||
|
247052df5f | ||
|
8eb28555bc | ||
|
73132475dc | ||
|
42c6487ff3 | ||
|
8d2ca25fd6 | ||
|
5c5919a7eb | ||
|
34cdbfc852 | ||
|
1bc50194aa | ||
|
4a75236e74 | ||
|
64b2f881c4 | ||
|
4709ddea5d | ||
|
6ef49152f3 | ||
|
1c44b0bc98 | ||
|
11bce8c17c | ||
|
b42fff1055 | ||
|
1b2e442513 | ||
|
a4d48077ba | ||
|
901e2527d8 | ||
|
f0839571d0 | ||
|
89d0d6ec93 | ||
|
922ab1d17b | ||
|
7c7be378bc | ||
|
ec01f8f54b | ||
|
5a094b44c4 | ||
|
3c657a6645 | ||
|
3129d44ff1 | ||
|
00306f82c5 | ||
|
7def676a17 | ||
|
6c48735854 | ||
|
a0b1831cdb | ||
|
db9fb8480a | ||
|
c138e2ffb4 | ||
|
473c45794e | ||
|
a12aa81d73 | ||
|
0033e279f1 | ||
|
a25e98d0cb | ||
|
bc65480f27 | ||
|
8582cda124 | ||
|
d963dfdbb6 | ||
|
f7e9c109f6 | ||
|
30c3004f27 | ||
|
4f049fd94b | ||
|
f98d1c95cc | ||
|
a2b5c0247b | ||
|
28bda9fa41 | ||
|
18aeeab041 | ||
|
c7427a5f7c | ||
|
03aa6c7d3a | ||
|
10077ae750 | ||
|
74eec25285 | ||
|
b6055479a1 | ||
|
69b781419f | ||
|
da6db24f9e | ||
|
2b66723d42 | ||
|
00a3e25714 | ||
|
8ccbd2d8f9 | ||
|
8307f26099 | ||
|
c686f7eefc | ||
|
311c7b1158 | ||
|
a17325f028 | ||
|
b734097d16 | ||
|
afaf077aca | ||
|
bf14af6a1f | ||
|
e72faef839 | ||
|
b274bafe8e | ||
|
7bed967755 | ||
|
944b81b71c | ||
|
cd529d53ae | ||
|
0d680a58f3 | ||
|
b30d519523 | ||
|
83932e1725 | ||
|
4ce0e39760 | ||
|
84232f25f0 | ||
|
2daedf8fd5 | ||
|
fe084a4478 | ||
|
5bf9646a76 | ||
|
2b1f28e6c2 | ||
|
5b8bd6e64f | ||
|
426fd499ce | ||
|
17d3a5840d | ||
|
be49e1d383 | ||
|
daa98e8925 | ||
|
58784b7568 | ||
|
419a183167 | ||
|
675b4bde14 | ||
|
ee6ee99577 | ||
|
3bc1f69e75 | ||
|
5b9df6d5f2 | ||
|
9f062ec1b8 | ||
|
b52a47bd03 | ||
|
5e20134f4f | ||
|
89d267d6a2 | ||
|
607bc42f59 | ||
|
880757fb5d | ||
|
c8acc6a12e | ||
|
7d4c2442da | ||
|
e5255b0c7c | ||
|
ac3ef9b6fc | ||
|
7b5a41c3ff | ||
|
d5b0d2a886 | ||
|
4d60447242 | ||
|
78bee3dc59 | ||
|
e2db958510 | ||
|
16440072fb | ||
|
be2dd6dc32 | ||
|
189bde7c9c | ||
|
6a4760e291 | ||
|
c082bb97e0 | ||
|
c8e14f91e7 | ||
|
6032d096ec | ||
|
defa9a2270 | ||
|
77a913f858 | ||
|
6e3fa974ba | ||
|
7926055b97 | ||
|
ffd10e656e | ||
|
59c1828078 | ||
|
6164271fe8 | ||
|
26ba35933d | ||
|
87359937c9 | ||
|
9b938f6515 | ||
|
6c3913785d | ||
|
542cf3147d | ||
|
fb9828badc | ||
|
2505ac3f98 | ||
|
fde8548166 | ||
|
fe91295704 | ||
|
15b99c5749 | ||
|
9d66ca4a49 | ||
|
b749a27f86 | ||
|
083212cffe | ||
|
c4e8756210 | ||
|
3a6448f727 | ||
|
fe18df25ba | ||
|
db65460ec0 | ||
|
0ad3eceb82 | ||
|
a376d6e361 | ||
|
45c7f3f3ca | ||
|
238de59a2a | ||
|
96255e51d2 | ||
|
18c3223105 | ||
|
b9e97792f3 | ||
|
cbce9b8637 | ||
|
5ab90b85da | ||
|
f3e1e8a2c7 | ||
|
e41b292e54 | ||
|
86928bbb2d | ||
|
2f5ec8b5bf | ||
|
14ac6446de | ||
|
260a9723a4 | ||
|
4e7b000dcd | ||
|
2254e4c57e | ||
|
25a27733b9 | ||
|
6ab520984c | ||
|
04d7106956 | ||
|
db5589f2aa | ||
|
d06dbbb4bd | ||
|
b7a62bd9e7 | ||
|
93ad9a3aa6 | ||
|
f1855174f0 | ||
|
a2dedba0ef | ||
|
5a65f445f0 | ||
|
f52289b2c3 | ||
|
3b5ea0f15f | ||
|
238bcb8698 | ||
|
3ee8bcad8c | ||
|
f0a51bafbe | ||
|
944f3bd329 | ||
|
8bb7b2e88b | ||
|
aab0b0b4bf | ||
|
083d6c5125 | ||
|
c2167a2c5f | ||
|
1a695e0451 | ||
|
8847f325ed | ||
|
94c9da468e | ||
|
24b38407e4 | ||
|
f49d1ae860 | ||
|
8b3b541a56 | ||
|
a974e84ad1 | ||
|
c4f4115bcb | ||
|
3c5adbee31 | ||
|
55645e3730 | ||
|
d918bb568c | ||
|
b1bff62bf7 | ||
|
d11d389ae4 | ||
|
a73c159160 | ||
|
7adf102d8d | ||
|
e4d3ff623a | ||
|
2433d59f00 | ||
|
8c68e76c3e | ||
|
0b204de5a9 | ||
|
93c811ab70 | ||
|
3ff861099a | ||
|
f22762539f | ||
|
677442a3c0 | ||
|
b73f12cdba | ||
|
28fbb61e81 | ||
|
c1104d1cd6 | ||
|
e346702292 | ||
|
90887779ea | ||
|
a941b1437c | ||
|
04bdcbd490 | ||
|
87a815fd6f | ||
|
d623848c87 | ||
|
46abd0cc42 | ||
|
e315325d91 | ||
|
f3fc083330 | ||
|
92cb57eb7b | ||
|
d645fbff2f | ||
|
8486f4d43a | ||
|
60b1a05894 | ||
|
f955d63707 | ||
|
f106019938 | ||
|
2473249c8b | ||
|
d13dc4fba3 | ||
|
41a0af032c | ||
|
70cf7b0c5a | ||
|
14f6788ab9 | ||
|
bb67049d90 | ||
|
ae2162beaf | ||
|
19f2c5e07f | ||
|
8abc5b3889 | ||
|
4d37c28bc7 | ||
|
cc0933eee4 | ||
|
2de9a804a0 | ||
|
ffeb2e91f4 | ||
|
8cf5ec9e5a | ||
|
ea0526f29a | ||
|
cfcb3a69e5 | ||
|
e3e0378857 | ||
|
ccc3809daa | ||
|
c97786e12c | ||
|
400071879f | ||
|
4cd6e20c91 | ||
|
460e3ad395 | ||
|
6f08bd6fc5 | ||
|
eed3a749db | ||
|
6587d12fbd | ||
|
f8dd68ecc4 | ||
|
f0aef2b853 | ||
|
7d27df1b97 | ||
|
457ec86c25 | ||
|
a24c66958f | ||
|
617628b886 | ||
|
6b7e623d33 | ||
|
5ca85b7e83 | ||
|
5965bf3332 | ||
|
baf2dd293b | ||
|
2cc19e7e32 | ||
|
53ab6f8569 | ||
|
cf8faac7ef | ||
|
86947a384d | ||
|
22855279bd | ||
|
e56fdecdc6 | ||
|
dc75a5812f | ||
|
33e20c9969 | ||
|
109204897f | ||
|
3b3a2d62f8 | ||
|
b1b4b3fb63 | ||
|
d583c68de5 | ||
|
d360f30af6 | ||
|
ed033565a4 | ||
|
2d6acfae1b | ||
|
10da894124 | ||
|
6dda8f21e4 | ||
|
1a9d759002 | ||
|
df24e13eb5 | ||
|
2ab19937af | ||
|
390b86cd8e | ||
|
423aba5bab | ||
|
dc0b9231cd | ||
|
3b177bedf8 | ||
|
12ce719213 | ||
|
320433b1bf | ||
|
7f35e2280e | ||
|
c514d988df | ||
|
749a080397 | ||
|
b105a12505 | ||
|
85a438a40f | ||
|
877260a243 |
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -28,7 +28,7 @@ To help us understand the issue, please fill-in as much of the following informa
|
||||
### Please tell us about your environment:
|
||||
|
||||
- [ ] Node-RED version:
|
||||
- [ ] node.js version:
|
||||
- [ ] Node.js version:
|
||||
- [ ] npm version:
|
||||
- [ ] Platform/OS:
|
||||
- [ ] Browser:
|
||||
|
2
.github/ISSUE_TEMPLATE/--bug_report.md
vendored
@@ -33,7 +33,7 @@ To help us understand the issue, please fill-in as much of the following informa
|
||||
### Please tell us about your environment:
|
||||
|
||||
- [ ] Node-RED version:
|
||||
- [ ] node.js version:
|
||||
- [ ] Node.js version:
|
||||
- [ ] npm version:
|
||||
- [ ] Platform/OS:
|
||||
- [ ] Browser:
|
||||
|
7
.github/ISSUE_TEMPLATE/-anything-else.md
vendored
@@ -7,8 +7,11 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack).
|
||||
Please DO NOT raise an issue.
|
||||
|
||||
You could also consider asking a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/node-red) and tag it `node-red`.
|
||||
We DO NOT use the issue tracker for general support or feature requests. Only bug reports should be raised here using the 'Bug report' template.
|
||||
|
||||
For general support, 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.
|
||||
|
||||
For feature requests, please use the Node-RED Forum](https://discourse.nodered.org). Many ideas have already been discussed there and you should search that for your request before starting a new discussion.
|
||||
|
@@ -9,5 +9,3 @@ matrix:
|
||||
before_script:
|
||||
- npm install -g istanbul coveralls
|
||||
- node_js: "8"
|
||||
allow_failures:
|
||||
- node_js: "12"
|
||||
|
243
CHANGELOG.md
@@ -1,3 +1,223 @@
|
||||
#### 1.0.3: Maintenance Release
|
||||
|
||||
Runtime
|
||||
- Increase timeouts in Subflow tests to minimise false positives
|
||||
- Update grunt-sass and add node-sass for node12 support
|
||||
- Fix timings of Delay node tests
|
||||
- #2340 Update JSONata to 1.7.0
|
||||
- Bump https-proxy-agent version
|
||||
- #2332 Fix error handling of nodes with multiple input handlers
|
||||
- Add script to generate npm publish script
|
||||
- #2371 Ensure folder is present before write (e.g. flows file not in user folder)
|
||||
- #2371 Handle windows UNC '\\' paths
|
||||
- #2366 Handle logging of non-JSON encodable objects
|
||||
|
||||
Editor
|
||||
- #2328 Fix language handling in subflow node
|
||||
- Use default language if lng param not set in i18n req
|
||||
- #2326 Fix palette editor search visualization
|
||||
- #2375 Subflow status not showing i18n version of contained core nodes status
|
||||
- Fix inverse of 'replace' editor event
|
||||
- #2376 Fallback to base language files if present
|
||||
- #2373 Support UI testing on the latest Google Chrome
|
||||
- #2364 Add tooltip to expand button in markdown editor
|
||||
- #2363 Support ctrl key to select tabs for Windows
|
||||
- #2356 Make JSONata help initially shown in expression editor
|
||||
- #2355 Prohibit line break in type menu of typedInput
|
||||
|
||||
Nodes
|
||||
- Delay: Fix delay to not pass through .reset and .flush props consistently
|
||||
- #2352 File: Using the ‘a msg per line’ the last line does not get msg.topic passed
|
||||
- #2339 HTTP Request: Check auth type on opening
|
||||
- HTTP Request: add units info
|
||||
- #2372 MQTT/WS: Improved proxy support for MQTT and WebSocket nodes
|
||||
- #2370 MQTT: Add clarification that MQTT Out requires payload to send msg
|
||||
|
||||
|
||||
#### 1.0.2: Maintenance Release
|
||||
|
||||
Runtime
|
||||
- Allow node.status() to be passed number/bool types
|
||||
- Allow node emitted events to have multiple arguments
|
||||
- #2323 Fixed docstrings to have them match the function signature (name of parameters).
|
||||
- #2318 NLS: Unify translations of "boolean"
|
||||
|
||||
Editor
|
||||
- Ensure node status is refreshed whenever node is edited
|
||||
- #2315 #2316 Ensure z property included in full message debug payload
|
||||
- #2321 Fixed editor.json (JA nls)
|
||||
- #2313 Fix element to collapse items in visual JSON editor
|
||||
- #2314 Insert divider in menu by calling RED.menu.addItem('id', null);
|
||||
|
||||
Nodes
|
||||
- Change: Fixup use of node.done
|
||||
- #2322 Template: Fix invalid JSON data in template node docs
|
||||
- #2320 File: Fixed a typo in 10-file.html (JA nls)
|
||||
- #2312 Template: Remove unnecessary comma in help text
|
||||
- #2319 Inject: Interval of inject node should be 596 hours or less.
|
||||
|
||||
#### 1.0.1: Maintenance Release
|
||||
|
||||
Runtime
|
||||
- #2301 Add env vars to enable safe mode and projects
|
||||
- `NODE_RED_ENABLE_SAFE_MODE`
|
||||
- `NODE_RED_ENABLE_PROJECTS`
|
||||
|
||||
Editor
|
||||
- #2308 Fix grid setting
|
||||
- #2306 i18n support in tooltips
|
||||
- Fix error when setting typedInput to boolean true/false
|
||||
- #2299 Fix SVG icons in IE11
|
||||
- #2303 Fix issue where subflow color did not update when not on a flow
|
||||
|
||||
Nodes
|
||||
- #2297 TLS: Allow TLS config node to provide just CA cert
|
||||
- #2307 Inject: Fix width on inject node property
|
||||
- #2305 Switch: Let switch node between rule work both ways round
|
||||
- Range: Add example to range node info and make use of target consistent
|
||||
- Join: node must clone group message before sending
|
||||
|
||||
|
||||
#### 1.0.0: Milestone Release
|
||||
|
||||
Editor
|
||||
- Add click-on-tooltip to close
|
||||
- Fix node draggable handling
|
||||
- Ensure complete node scope property is remapped on import
|
||||
- Update i18n for project feature
|
||||
- Fix menu hiding function for flow editor
|
||||
- Normalise default subflow color references
|
||||
- Hide header text of very small screens to deploy is visible
|
||||
- Fix tab access on touch screens
|
||||
- Update radialMenu to use standard theme colours
|
||||
- Fix undefined reference loading on mobile
|
||||
- Allow word breaking of node name with long word
|
||||
- Enable wrap mode in Markdown editor
|
||||
- Maximize the size of markdown editor
|
||||
|
||||
Nodes
|
||||
- remove legacy error option from file in mode
|
||||
- Change MQTT node default 3.1 compatibility mode to false
|
||||
- Show clear debug shortcut in tooltip
|
||||
- Fix file-in port labels for all 4 options
|
||||
- Add extra comment re Mustache escapes to Template info
|
||||
- Fix typo in complete node
|
||||
- Allow Function node output input to go to 0
|
||||
|
||||
#### 1.0.0-beta.4: Beta Release
|
||||
|
||||
Runtime
|
||||
- Clone the first message passed to node.send in Function node
|
||||
|
||||
Editor
|
||||
- Move flow-status button to footer for consistency
|
||||
- Fix node hover effect to prevent jumping position
|
||||
- Filter quick-add properly when splicing a wire
|
||||
- Mark workspace dirty when deleting link node link Fixes #2274
|
||||
- Add red-ui-button class to strategy login button
|
||||
- Fix padding of subflow locale select Closes #2276
|
||||
- Update info text of complete node & add JP text
|
||||
- Add class red-ui-button to cancel button
|
||||
- Add css class to login submit button (#2275)
|
||||
- Realign subflow output port labels
|
||||
- Move context sidebar auto-refresh option to individual sections
|
||||
- Update Japanese message catalogue
|
||||
- Fix subflow UI for select
|
||||
- remove padding before label text for SUBFLOW UI row
|
||||
- Allow SUBFLOW UI label row without variable name
|
||||
|
||||
Nodes
|
||||
- Remove old rc option from exec node for 1.0
|
||||
- Add python and SQL to template language options
|
||||
- Fix Switch node display of jsonata_exp type
|
||||
- Remove sentiment from core nodes
|
||||
|
||||
#### 1.0.0-beta.3: Beta Release
|
||||
|
||||
Runtime
|
||||
- [FEATURE] Add Node Done API - make message passing async
|
||||
- Ensure the subflow stop promise is waiting for before restarting
|
||||
- Limit the regex for the /nodes/ api end points
|
||||
- Add error event handler to ssh-keygen child_process Fixes #2255
|
||||
- Fix default value handling on context array access Fixes #2252
|
||||
- Remove all ui test dependencies from package.json
|
||||
- Add req back to audit log events and extend to Projects api
|
||||
- Ensure 2nd arg to node.error is an object Fixes #2228
|
||||
- Use a more atomic process for writing context files Fixes #2271
|
||||
|
||||
|
||||
Editor
|
||||
- [FEATURE] Change core node categories
|
||||
- [FEATURE] Subflow Instance property UI (#2236)
|
||||
- [FEATURE] Add visual JSON editor
|
||||
- [FEATURE] Add Action List dialog
|
||||
- [FEATURE] Add new shortcut to clear debug message list - ctrl-alt-l
|
||||
- [FEATURE] Add show-library dialog actions
|
||||
- [FEATURE] Add shift-cursor handling for moving quick-add dialog
|
||||
- [FEATURE] Add enable/disable-flow actions
|
||||
- [FEATURE] Add actions to change deploy type
|
||||
- [FEATURE] Allow config nodes to be disabled, tidy css and add actions
|
||||
- [FEATURE] Add default shortcut (ctrl-d) for deploy
|
||||
- [FEATURE] Initial implementation of redo (un-undo) - ctrl-y
|
||||
- [FEATURE] add support for specifying subflow template color
|
||||
- [FEATURE] Use ctrl-click on wire to splice node in place
|
||||
- [FEATURE] Allow search results to show more than 25 results
|
||||
- [FEATURE] Allow a node to change if it has an input port Closes #2268
|
||||
- Revealing node position needs to account for zoom level Fixes #2172
|
||||
- Fix typedInput option selection Fixes #2174
|
||||
- Fix palette node id handling so search works Fixes #2173
|
||||
- Add popover tooltips to debug sidebar,function and template
|
||||
- Add popovers to context sidebar mini buttons
|
||||
- Ensure node status icon is shown when value set
|
||||
- Revert treeList children function signature change
|
||||
- Restore tray component css for compatibility. Mark as deprecated
|
||||
- fix function name & string compare function
|
||||
- Handle empty list of example flows Fixes #2171
|
||||
- Ensure library list has an item selected when opened
|
||||
- Ensure tooltip popover doesn't replace normal popover
|
||||
- Fix clipboard export download button
|
||||
- Ensure input box has focus on repeated quick add
|
||||
- Fix width calculation of typedInput
|
||||
- Remove some hardcoded css colors
|
||||
- Fix display of node help when clicking in palette Fixes #2194
|
||||
- Ensure node help is loaded in the right language Fixes #2195
|
||||
- Do not allow tab focus on clipboard hidden element
|
||||
- Fix undefined error on typedInput due to valueLabel used before being added
|
||||
- Fix undo of flow disable state change
|
||||
- Fix select-all action in main view
|
||||
- Fix delete-all action on config node sidebar
|
||||
- Update UI tests for new editor css
|
||||
- Add insertItemAt doc to editableList
|
||||
- Ensure focus returns to the right element after dialogs shown
|
||||
- Set autocomplete to disabled in form input elements
|
||||
- Update all node icons to SVG
|
||||
- Handle png/svg fallback for def.icon values. Remove old pngs
|
||||
- Ignore empty examples directories (don't add to import menu)
|
||||
- better handle example file at any depth - #2222
|
||||
- Properly escape node types in palette
|
||||
- Ensure session expiry timeout doesn't exceed limit
|
||||
- Use node/tab map to make filterNodes more efficient
|
||||
- Rearrange contents of subflow template settings tab
|
||||
- Handle undefined node.\_def in edit stack title.
|
||||
- fix converting selection to subflow
|
||||
- Fix inserting new subflow node to existing wire between nodes
|
||||
- Support displaying falsey node status values Fixes #2246
|
||||
- Remove tab menu from node property UI for subflow and config nodes
|
||||
- Mark workspace dirty when shift-click-drag detaches wires Fixes #2260
|
||||
- Fix subflow category change on palette
|
||||
|
||||
|
||||
Nodes
|
||||
- Remove pi gpi, twitter, email and feedparser nodes from core
|
||||
- Fix error handling in Websocket broadcast function Fixes #2182
|
||||
- Handle websocket item being parseable but not an object better
|
||||
- stop join tripping up if last message of buffer is blank.
|
||||
- Add support for env var propety in switch node
|
||||
- Improve handling of file upload in request node
|
||||
- Add "has key" rule to switch node + tests
|
||||
- Optimise generation of switch node edit dialog
|
||||
- Add keep-alive option to HTTP Request - #2261
|
||||
|
||||
#### 1.0.0-beta.2: Beta Release
|
||||
|
||||
Runtime
|
||||
@@ -46,8 +266,29 @@ Nodes
|
||||
- Add expand editor button to Template node
|
||||
- Update catch/status nodes to use selectNodes api and treeList
|
||||
|
||||
#### 0.20.8: Maintenance Release
|
||||
|
||||
- Sanitize tab name in edit dialog
|
||||
- Pass httpServer to runtime even when httpAdmin disabled Fixes #2272
|
||||
|
||||
#### 0.20.7: Maintenance Release
|
||||
|
||||
- Update jsonata to 1.6.5 which should fix #2183
|
||||
- Ensure the subflow stop promise is waiting for before restarting
|
||||
- Properly escape node types in palette
|
||||
|
||||
#### 0.20.6: Maintenance Release
|
||||
|
||||
- Revealing node position needs to account for zoom level Fixes #2172
|
||||
- stop join tripping up if last message of buffer is blank.
|
||||
- Improve handling of file upload in request node
|
||||
- Handle subflow internal node wired to a non-existant node Fixes #2202
|
||||
- Do not save subflow env vars with blank names
|
||||
- Don't allow a link node virtual wire to connect to normal port
|
||||
- Clear HTTP Request node authType when auth disabled Fixes #2215
|
||||
- Fix parsing of content-type header Fixes #2216
|
||||
- Fix join node reset issue with merging objects
|
||||
- Copy data-i18n attribute on TypedInput Fixes #2211
|
||||
|
||||
#### 0.20.5: Maintenance Release
|
||||
|
||||
@@ -709,7 +950,7 @@ Nodes
|
||||
- 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
|
||||
- Introduce `nodeMessageBufferMaxLength` 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)
|
||||
|
@@ -26,7 +26,7 @@ relevant nodes, press Ctrl-E and copy the flow data from the Export dialog.
|
||||
At a minimum, please include:
|
||||
|
||||
- Version of Node-RED - either release number if you downloaded a zip, or the first few lines of `git log` if you are cloning the repository directly.
|
||||
- Version of node.js - what does `node -v` say?
|
||||
- Version of Node.js - what does `node -v` say?
|
||||
|
||||
## Feature requests
|
||||
|
||||
|
72
Gruntfile.js
@@ -16,6 +16,7 @@
|
||||
|
||||
var path = require("path");
|
||||
var fs = require("fs-extra");
|
||||
var sass = require("node-sass");
|
||||
|
||||
module.exports = function(grunt) {
|
||||
|
||||
@@ -27,7 +28,7 @@ module.exports = function(grunt) {
|
||||
|
||||
var nonHeadless = grunt.option('non-headless');
|
||||
if (nonHeadless) {
|
||||
process.env.NODE_RED_NON_HEADLESS = 'true';
|
||||
process.env.NODE_RED_NON_HEADLESS = true;
|
||||
}
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
@@ -79,20 +80,20 @@ module.exports = function(grunt) {
|
||||
//"loopfunc": true, // allow functions to be defined in loops
|
||||
//"sub": true // don't warn that foo['bar'] should be written as foo.bar
|
||||
},
|
||||
all: [
|
||||
'Gruntfile.js',
|
||||
'red.js',
|
||||
'packages/**/*.js'
|
||||
],
|
||||
core: {
|
||||
files: {
|
||||
src: [
|
||||
'Gruntfile.js',
|
||||
'red.js',
|
||||
'packages/**/*.js',
|
||||
]
|
||||
}
|
||||
},
|
||||
// all: [
|
||||
// 'Gruntfile.js',
|
||||
// 'red.js',
|
||||
// 'packages/**/*.js'
|
||||
// ],
|
||||
// core: {
|
||||
// files: {
|
||||
// src: [
|
||||
// 'Gruntfile.js',
|
||||
// 'red.js',
|
||||
// 'packages/**/*.js',
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
nodes: {
|
||||
files: {
|
||||
src: [ 'nodes/core/*/*.js' ]
|
||||
@@ -100,7 +101,7 @@ module.exports = function(grunt) {
|
||||
},
|
||||
editor: {
|
||||
files: {
|
||||
src: [ 'editor/js/**/*.js' ]
|
||||
src: [ 'packages/node_modules/@node-red/editor-client/src/js/**/*.js' ]
|
||||
}
|
||||
},
|
||||
tests: {
|
||||
@@ -169,6 +170,7 @@ module.exports = function(grunt) {
|
||||
"packages/node_modules/@node-red/editor-client/src/js/ui/library.js",
|
||||
"packages/node_modules/@node-red/editor-client/src/js/ui/notifications.js",
|
||||
"packages/node_modules/@node-red/editor-client/src/js/ui/search.js",
|
||||
"packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js",
|
||||
"packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js",
|
||||
"packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js",
|
||||
"packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js",
|
||||
@@ -219,6 +221,7 @@ module.exports = function(grunt) {
|
||||
sass: {
|
||||
build: {
|
||||
options: {
|
||||
implementation: sass,
|
||||
outputStyle: 'compressed'
|
||||
},
|
||||
files: [{
|
||||
@@ -275,7 +278,7 @@ module.exports = function(grunt) {
|
||||
files: [
|
||||
'packages/node_modules/@node-red/editor-client/src/js/**/*.js'
|
||||
],
|
||||
tasks: ['copy:build','concat','uglify','attachCopyright:js']
|
||||
tasks: ['copy:build','concat',/*'uglify',*/ 'attachCopyright:js']
|
||||
},
|
||||
sass: {
|
||||
files: [
|
||||
@@ -495,7 +498,9 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-chmod');
|
||||
grunt.loadNpmTasks('grunt-jsonlint');
|
||||
grunt.loadNpmTasks('grunt-mocha-istanbul');
|
||||
grunt.loadNpmTasks('grunt-webdriver');
|
||||
if (fs.existsSync(path.join("node_modules", "grunt-webdriver"))) {
|
||||
grunt.loadNpmTasks('grunt-webdriver');
|
||||
}
|
||||
grunt.loadNpmTasks('grunt-jsdoc');
|
||||
grunt.loadNpmTasks('grunt-jsdoc-to-markdown');
|
||||
grunt.loadNpmTasks('grunt-npm-command');
|
||||
@@ -554,12 +559,25 @@ module.exports = function(grunt) {
|
||||
});
|
||||
|
||||
grunt.registerTask('verifyUiTestDependencies', function() {
|
||||
if (!fs.existsSync(path.join("node_modules", "chromedriver"))) {
|
||||
grunt.fail.fatal('You need to run "npm install chromedriver@2" before running UI test.');
|
||||
if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) {
|
||||
grunt.fail.fatal('You need to install the UI test dependencies first.\nUse the script in "scripts/install-ui-test-dependencies.sh"');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
grunt.registerTask('generatePublishScript',
|
||||
'Generates a script to publish build output to npm',
|
||||
function () {
|
||||
const done = this.async();
|
||||
const generatePublishScript = require("./scripts/generate-publish-script.js");
|
||||
generatePublishScript().then(function(output) {
|
||||
grunt.log.writeln(output);
|
||||
|
||||
const filePath = path.join(grunt.config.get('paths.dist'),"modules","publish.sh");
|
||||
grunt.file.write(filePath,output);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
grunt.registerTask('setDevEnv',
|
||||
'Sets NODE_ENV=development so non-minified assets are used',
|
||||
function () {
|
||||
@@ -578,9 +596,15 @@ module.exports = function(grunt) {
|
||||
'Runs code style check on editor code',
|
||||
['jshint:editor']);
|
||||
|
||||
grunt.registerTask('test-ui',
|
||||
'Builds editor content then runs unit tests on editor ui',
|
||||
['verifyUiTestDependencies','build','jshint:editor','webdriver:all']);
|
||||
if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) {
|
||||
grunt.registerTask('test-ui',
|
||||
'Builds editor content then runs unit tests on editor ui',
|
||||
['verifyUiTestDependencies']);
|
||||
} else {
|
||||
grunt.registerTask('test-ui',
|
||||
'Builds editor content then runs unit tests on editor ui',
|
||||
['verifyUiTestDependencies','build','jshint:editor','webdriver:all']);
|
||||
}
|
||||
|
||||
grunt.registerTask('test-nodes',
|
||||
'Runs unit tests on core nodes',
|
||||
@@ -596,7 +620,7 @@ module.exports = function(grunt) {
|
||||
|
||||
grunt.registerTask('release',
|
||||
'Create distribution zip file',
|
||||
['build','verifyPackageDependencies','clean:release','mkdir:release','chmod:release','compress:release','pack-modules']);
|
||||
['build','verifyPackageDependencies','clean:release','mkdir:release','chmod:release','compress:release','pack-modules','generatePublishScript']);
|
||||
|
||||
grunt.registerTask('pack-modules',
|
||||
'Create module pack files for release',
|
||||
|
@@ -5,9 +5,9 @@ http://nodered.org
|
||||
[](https://travis-ci.org/node-red/node-red)
|
||||
[](https://coveralls.io/r/node-red/node-red?branch=master)
|
||||
|
||||
A visual tool for wiring the Internet of Things.
|
||||
Low-code programming for event-driven applications.
|
||||
|
||||

|
||||

|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -56,7 +56,7 @@ This project adheres to the [Contributor Covenant 1.4](http://contributor-covena
|
||||
|
||||
## Authors
|
||||
|
||||
Node-RED is a project of the [JS Foundation](http://js.foundation).
|
||||
Node-RED is a project of the [OpenJS Foundation](https://openjsf.org).
|
||||
|
||||
It was created by [IBM Emerging Technology](https://www.ibm.com/blogs/emerging-technology/).
|
||||
|
||||
@@ -67,4 +67,4 @@ It was created by [IBM Emerging Technology](https://www.ibm.com/blogs/emerging-t
|
||||
|
||||
## Copyright and license
|
||||
|
||||
Copyright JS Foundation and other contributors, http://js.foundation under [the Apache 2.0 license](LICENSE).
|
||||
Copyright JS Foundation and other contributors, https://openjsf.org under [the Apache 2.0 license](LICENSE).
|
||||
|
13
SECURITY.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 1.0.0 | :white_check_mark: |
|
||||
| 0.20.x | :white_check_mark: |
|
||||
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report any potential security issues to `team@nodered.org`. This will notify the core project team who will respond accordingly.
|
74
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "node-red",
|
||||
"version": "1.0.0-beta.2",
|
||||
"description": "A visual tool for wiring the Internet of Things",
|
||||
"version": "1.0.3",
|
||||
"description": "Low-code programming for event-driven applications",
|
||||
"homepage": "http://nodered.org",
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
@@ -24,7 +24,7 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"ajv": "6.10.0",
|
||||
"ajv": "6.10.2",
|
||||
"basic-auth": "2.0.1",
|
||||
"bcryptjs": "2.4.3",
|
||||
"body-parser": "1.19.0",
|
||||
@@ -34,85 +34,79 @@
|
||||
"cookie": "0.4.0",
|
||||
"cookie-parser": "1.4.4",
|
||||
"cors": "2.8.5",
|
||||
"cron": "1.7.1",
|
||||
"cron": "1.7.2",
|
||||
"denque": "1.4.1",
|
||||
"express": "4.17.0",
|
||||
"express-session": "1.16.1",
|
||||
"fs-extra": "8.0.1",
|
||||
"express": "4.17.1",
|
||||
"express-session": "1.17.0",
|
||||
"fs-extra": "8.1.0",
|
||||
"fs.notify": "0.0.4",
|
||||
"hash-sum": "1.0.2",
|
||||
"https-proxy-agent": "2.2.1",
|
||||
"hash-sum": "2.0.0",
|
||||
"https-proxy-agent": "2.2.4",
|
||||
"i18next": "15.1.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"iconv-lite": "0.5.0",
|
||||
"is-utf8": "0.2.1",
|
||||
"js-yaml": "3.13.1",
|
||||
"json-stringify-safe": "5.0.1",
|
||||
"jsonata": "1.6.4",
|
||||
"jsonata": "1.7.0",
|
||||
"media-typer": "1.1.0",
|
||||
"memorystore": "1.6.1",
|
||||
"mime": "2.4.3",
|
||||
"mime": "2.4.4",
|
||||
"mqtt": "2.18.8",
|
||||
"multer": "1.4.1",
|
||||
"mustache": "3.0.1",
|
||||
"node-red-node-email": "^1.4.0",
|
||||
"node-red-node-feedparser": "^0.1.14",
|
||||
"node-red-node-rbe": "^0.2.4",
|
||||
"node-red-node-sentiment": "^0.1.3",
|
||||
"node-red-node-tail": "^0.0.2",
|
||||
"node-red-node-twitter": "^1.1.4",
|
||||
"multer": "1.4.2",
|
||||
"mustache": "3.0.2",
|
||||
"node-red-node-rbe": "^0.2.6",
|
||||
"node-red-node-sentiment": "^0.1.6",
|
||||
"node-red-node-tail": "^0.1.0",
|
||||
"nopt": "4.0.1",
|
||||
"oauth2orize": "1.11.0",
|
||||
"on-headers": "1.0.2",
|
||||
"passport": "0.4.0",
|
||||
"passport-http-bearer": "1.0.1",
|
||||
"passport-oauth2-client-password": "0.1.2",
|
||||
"raw-body": "2.4.0",
|
||||
"raw-body": "2.4.1",
|
||||
"request": "2.88.0",
|
||||
"semver": "6.0.0",
|
||||
"uglify-js": "3.5.15",
|
||||
"semver": "6.3.0",
|
||||
"uglify-js": "3.6.9",
|
||||
"when": "3.7.8",
|
||||
"ws": "6.2.1",
|
||||
"xml2js": "0.4.19"
|
||||
"xml2js": "0.4.22"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"bcrypt": "3.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "~1.0.3",
|
||||
"grunt": "~1.0.4",
|
||||
"grunt-chmod": "~1.1.1",
|
||||
"grunt-cli": "~1.3.2",
|
||||
"grunt-concurrent": "~2.3.1",
|
||||
"grunt-contrib-clean": "~1.1.0",
|
||||
"grunt-contrib-compress": "~1.4.0",
|
||||
"grunt-contrib-clean": "~2.0.0",
|
||||
"grunt-contrib-compress": "~1.5.0",
|
||||
"grunt-contrib-concat": "~1.0.1",
|
||||
"grunt-contrib-copy": "~1.0.0",
|
||||
"grunt-contrib-jshint": "~1.1.0",
|
||||
"grunt-contrib-uglify": "~3.4.0",
|
||||
"grunt-contrib-jshint": "~2.1.0",
|
||||
"grunt-contrib-uglify": "~4.0.1",
|
||||
"grunt-contrib-watch": "~1.1.0",
|
||||
"grunt-jsdoc": "^2.2.1",
|
||||
"grunt-jsdoc-to-markdown": "^4.0.0",
|
||||
"grunt-jsonlint": "~1.1.0",
|
||||
"grunt-jsonlint": "~2.0.0",
|
||||
"grunt-mkdir": "~1.0.0",
|
||||
"grunt-mocha-istanbul": "5.0.2",
|
||||
"grunt-nodemon": "~0.4.2",
|
||||
"grunt-npm-command": "~0.1.2",
|
||||
"grunt-sass": "~2.0.0",
|
||||
"grunt-sass": "~3.1.0",
|
||||
"grunt-simple-mocha": "~0.4.1",
|
||||
"grunt-webdriver": "^2.0.3",
|
||||
"http-proxy": "^1.16.2",
|
||||
"http-proxy": "1.18.0",
|
||||
"istanbul": "0.4.5",
|
||||
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
||||
"minami": "1.2.3",
|
||||
"mocha": "^5.2.0",
|
||||
"mosca": "^2.8.3",
|
||||
"node-red-node-test-helper": "^0.2.3",
|
||||
"node-sass": "^4.13.0",
|
||||
"should": "^8.4.0",
|
||||
"sinon": "1.17.7",
|
||||
"stoppable": "^1.1.0",
|
||||
"supertest": "3.4.2",
|
||||
"wdio-chromedriver-service": "^0.1.5",
|
||||
"wdio-mocha-framework": "^0.6.4",
|
||||
"wdio-spec-reporter": "^0.1.5",
|
||||
"webdriverio": "^4.14.1",
|
||||
"node-red-node-test-helper": "^0.2.2",
|
||||
"jsdoc-nr-template": "node-red/jsdoc-nr-template"
|
||||
"supertest": "3.4.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
@@ -30,7 +30,8 @@ module.exports = {
|
||||
scope: req.params.scope,
|
||||
id: req.params.id,
|
||||
key: req.params[0],
|
||||
store: req.query['store']
|
||||
store: req.query['store'],
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.context.getValue(opts).then(function(result) {
|
||||
res.json(result);
|
||||
@@ -45,7 +46,8 @@ module.exports = {
|
||||
scope: req.params.scope,
|
||||
id: req.params.id,
|
||||
key: req.params[0],
|
||||
store: req.query['store']
|
||||
store: req.query['store'],
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.context.delete(opts).then(function(result) {
|
||||
res.status(204).end();
|
||||
|
@@ -24,7 +24,8 @@ module.exports = {
|
||||
get: function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id
|
||||
id: req.params.id,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.flows.getFlow(opts).then(function(result) {
|
||||
return res.json(result);
|
||||
@@ -35,7 +36,8 @@ module.exports = {
|
||||
post: function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
flow: req.body
|
||||
flow: req.body,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.flows.addFlow(opts).then(function(id) {
|
||||
return res.json({id:id});
|
||||
@@ -47,7 +49,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
flow: req.body
|
||||
flow: req.body,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.flows.updateFlow(opts).then(function(id) {
|
||||
return res.json({id:id});
|
||||
@@ -58,7 +61,8 @@ module.exports = {
|
||||
delete: function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id
|
||||
id: req.params.id,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.flows.deleteFlow(opts).then(function() {
|
||||
res.status(204).end();
|
||||
|
@@ -27,7 +27,8 @@ module.exports = {
|
||||
return res.status(400).json({code:"invalid_api_version", message:"Invalid API Version requested"});
|
||||
}
|
||||
var opts = {
|
||||
user: req.user
|
||||
user: req.user,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.flows.getFlows(opts).then(function(result) {
|
||||
if (version === "v1") {
|
||||
@@ -46,7 +47,8 @@ module.exports = {
|
||||
}
|
||||
var opts = {
|
||||
user: req.user,
|
||||
deploymentType: req.get("Node-RED-Deployment-Type")||"full"
|
||||
deploymentType: req.get("Node-RED-Deployment-Type")||"full",
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
|
||||
if (opts.deploymentType !== 'reload') {
|
||||
|
@@ -48,13 +48,13 @@ module.exports = {
|
||||
// Nodes
|
||||
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll,apiUtil.errorHandler);
|
||||
adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post,apiUtil.errorHandler);
|
||||
adminApp.get(/\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler);
|
||||
adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler);
|
||||
adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.read"),nodes.getModule,apiUtil.errorHandler);
|
||||
adminApp.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.putModule,apiUtil.errorHandler);
|
||||
adminApp.delete(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.delete,apiUtil.errorHandler);
|
||||
adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.read"),nodes.getSet,apiUtil.errorHandler);
|
||||
adminApp.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.write"),nodes.putSet,apiUtil.errorHandler);
|
||||
adminApp.get(/^\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler);
|
||||
adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler);
|
||||
adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.read"),nodes.getModule,apiUtil.errorHandler);
|
||||
adminApp.put(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.putModule,apiUtil.errorHandler);
|
||||
adminApp.delete(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.delete,apiUtil.errorHandler);
|
||||
adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.read"),nodes.getSet,apiUtil.errorHandler);
|
||||
adminApp.put(/^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.write"),nodes.putSet,apiUtil.errorHandler);
|
||||
|
||||
// Context
|
||||
adminApp.get("/context/:scope(global)",needsPermission("context.read"),context.get,apiUtil.errorHandler);
|
||||
|
@@ -24,7 +24,8 @@ module.exports = {
|
||||
},
|
||||
getAll: function(req,res) {
|
||||
var opts = {
|
||||
user: req.user
|
||||
user: req.user,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
if (req.get("accept") == "application/json") {
|
||||
runtimeAPI.nodes.getNodeList(opts).then(function(list) {
|
||||
@@ -42,7 +43,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
module: req.body.module,
|
||||
version: req.body.version
|
||||
version: req.body.version,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.nodes.addModule(opts).then(function(info) {
|
||||
res.json(info);
|
||||
@@ -54,7 +56,8 @@ module.exports = {
|
||||
delete: function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
module: req.params[0]
|
||||
module: req.params[0],
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.nodes.removeModule(opts).then(function() {
|
||||
res.status(204).end();
|
||||
@@ -66,7 +69,8 @@ module.exports = {
|
||||
getSet: function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params[0] + "/" + req.params[2]
|
||||
id: req.params[0] + "/" + req.params[2],
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
if (req.get("accept") === "application/json") {
|
||||
runtimeAPI.nodes.getNodeInfo(opts).then(function(result) {
|
||||
@@ -87,7 +91,8 @@ module.exports = {
|
||||
getModule: function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
module: req.params[0]
|
||||
module: req.params[0],
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.nodes.getModuleInfo(opts).then(function(result) {
|
||||
res.send(result);
|
||||
@@ -106,7 +111,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params[0] + "/" + req.params[2],
|
||||
enabled: body.enabled
|
||||
enabled: body.enabled,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.nodes.setNodeSetState(opts).then(function(result) {
|
||||
res.send(result);
|
||||
@@ -125,7 +131,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
module: req.params[0],
|
||||
enabled: body.enabled
|
||||
enabled: body.enabled,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.nodes.setModuleState(opts).then(function(result) {
|
||||
res.send(result);
|
||||
@@ -139,7 +146,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
module: req.params[0],
|
||||
lang: req.query.lng
|
||||
lang: req.query.lng,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.nodes.getModuleCatalog(opts).then(function(result) {
|
||||
res.json(result);
|
||||
@@ -152,7 +160,8 @@ module.exports = {
|
||||
getModuleCatalogs: function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
lang: req.query.lng
|
||||
lang: req.query.lng,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.nodes.getModuleCatalogs(opts).then(function(result) {
|
||||
res.json(result);
|
||||
@@ -164,7 +173,8 @@ module.exports = {
|
||||
|
||||
getIcons: function(req,res) {
|
||||
var opts = {
|
||||
user: req.user
|
||||
user: req.user,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.nodes.getIconList(opts).then(function(list) {
|
||||
res.json(list);
|
||||
|
@@ -56,7 +56,7 @@ function expireSessions() {
|
||||
}
|
||||
if (nextExpiry < Number.MAX_SAFE_INTEGER) {
|
||||
// Allow 5 seconds grace
|
||||
expiryTimeout = setTimeout(expireSessions,(nextExpiry - Date.now()) + 5000)
|
||||
expiryTimeout = setTimeout(expireSessions,Math.min(2147483647,(nextExpiry - Date.now()) + 5000))
|
||||
}
|
||||
if (modified) {
|
||||
return storage.saveSessions(sessions);
|
||||
@@ -129,7 +129,7 @@ module.exports = {
|
||||
sessions[accessToken] = session;
|
||||
|
||||
if (!expiryTimeout) {
|
||||
expiryTimeout = setTimeout(expireSessions,(accessTokenExpiresAt - Date.now()) + 5000)
|
||||
expiryTimeout = setTimeout(expireSessions,Math.min(2147483647,(accessTokenExpiresAt - Date.now()) + 5000))
|
||||
}
|
||||
|
||||
return storage.saveSessions(sessions).then(function() {
|
||||
|
@@ -88,13 +88,13 @@ module.exports = {
|
||||
// Locales
|
||||
var locales = require("./locales");
|
||||
locales.init(runtimeAPI);
|
||||
editorApp.get(/locales\/(.+)\/?$/,locales.get,apiUtil.errorHandler);
|
||||
editorApp.get(/^\/locales\/(.+)\/?$/,locales.get,apiUtil.errorHandler);
|
||||
|
||||
// Library
|
||||
var library = require("./library");
|
||||
library.init(runtimeAPI);
|
||||
editorApp.get(/library\/([^\/]+)\/([^\/]+)(?:$|\/(.*))/,needsPermission("library.read"),library.getEntry);
|
||||
editorApp.post(/library\/([^\/]+)\/([^\/]+)\/(.*)/,needsPermission("library.write"),library.saveEntry);
|
||||
editorApp.get(/^\/library\/([^\/]+)\/([^\/]+)(?:$|\/(.*))/,needsPermission("library.read"),library.getEntry);
|
||||
editorApp.post(/^\/library\/([^\/]+)\/([^\/]+)\/(.*)/,needsPermission("library.write"),library.saveEntry);
|
||||
|
||||
|
||||
// Credentials
|
||||
|
@@ -15,7 +15,7 @@
|
||||
**/
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
//var apiUtil = require('../util');
|
||||
// var apiUtil = require('../util');
|
||||
|
||||
var i18n = require("@node-red/util").i18n; // TODO: separate module
|
||||
|
||||
@@ -41,7 +41,7 @@ module.exports = {
|
||||
var namespace = req.params[0];
|
||||
var lngs = req.query.lng;
|
||||
namespace = namespace.replace(/\.json$/,"");
|
||||
var lang = req.query.lng; //apiUtil.determineLangFromHeaders(req.acceptsLanguages() || []);
|
||||
var lang = req.query.lng || i18n.defaultLang; //apiUtil.determineLangFromHeaders(req.acceptsLanguages() || []);
|
||||
var prevLang = i18n.i.language;
|
||||
// Trigger a load from disk of the language if it is not the default
|
||||
i18n.i.changeLanguage(lang, function(){
|
||||
|
@@ -22,7 +22,8 @@ var needsPermission = require("../auth").needsPermission;
|
||||
|
||||
function listProjects(req,res) {
|
||||
var opts = {
|
||||
user: req.user
|
||||
user: req.user,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.listProjects(opts).then(function(result) {
|
||||
res.json(result);
|
||||
@@ -33,7 +34,8 @@ function listProjects(req,res) {
|
||||
function getProject(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id
|
||||
id: req.params.id,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getProject(opts).then(function(data) {
|
||||
if (data) {
|
||||
@@ -49,7 +51,8 @@ function getProjectStatus(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
remote: req.query.remote
|
||||
remote: req.query.remote,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getStatus(opts).then(function(data){
|
||||
if (data) {
|
||||
@@ -64,7 +67,8 @@ function getProjectStatus(req,res) {
|
||||
function getProjectRemotes(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id
|
||||
id: req.params.id,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getRemotes(opts).then(function(data) {
|
||||
res.json(data);
|
||||
@@ -98,7 +102,8 @@ module.exports = {
|
||||
app.post("/", needsPermission("projects.write"), function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
project: req.body
|
||||
project: req.body,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.createProject(opts).then(function(result) {
|
||||
res.json(result);
|
||||
@@ -112,7 +117,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
project: req.body
|
||||
project: req.body,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
|
||||
if (req.body.active) {
|
||||
@@ -150,7 +156,8 @@ module.exports = {
|
||||
app.delete("/:id", needsPermission("projects.write"), function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id
|
||||
id: req.params.id,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.deleteProject(opts).then(function() {
|
||||
res.status(204).end();
|
||||
@@ -168,7 +175,8 @@ module.exports = {
|
||||
app.get("/:id/files", needsPermission("projects.read"), function(req,res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id
|
||||
id: req.params.id,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getFiles(opts).then(function(data) {
|
||||
res.json(data);
|
||||
@@ -185,7 +193,8 @@ module.exports = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
path: req.params[0],
|
||||
tree: req.params.treeish
|
||||
tree: req.params.treeish,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getFile(opts).then(function(data) {
|
||||
res.json({content:data});
|
||||
@@ -199,7 +208,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
path: req.params[0]
|
||||
path: req.params[0],
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
|
||||
runtimeAPI.projects.revertFile(opts).then(function() {
|
||||
@@ -214,7 +224,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
path: req.params[0]
|
||||
path: req.params[0],
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.stageFile(opts).then(function() {
|
||||
getProjectStatus(req,res);
|
||||
@@ -228,7 +239,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
path: req.body.files
|
||||
path: req.body.files,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.stageFile(opts).then(function() {
|
||||
getProjectStatus(req,res);
|
||||
@@ -242,7 +254,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
message: req.body.message
|
||||
message: req.body.message,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.commit(opts).then(function() {
|
||||
getProjectStatus(req,res);
|
||||
@@ -256,7 +269,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
path: req.params[0]
|
||||
path: req.params[0],
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.unstageFile(opts).then(function() {
|
||||
getProjectStatus(req,res);
|
||||
@@ -269,7 +283,8 @@ module.exports = {
|
||||
app.delete("/:id/stage", needsPermission("projects.write"), function(req, res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id
|
||||
id: req.params.id,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.unstageFile(opts).then(function() {
|
||||
getProjectStatus(req,res);
|
||||
@@ -284,7 +299,8 @@ module.exports = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
path: req.params[0],
|
||||
type: req.params.type
|
||||
type: req.params.type,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getFileDiff(opts).then(function(data) {
|
||||
res.json({
|
||||
@@ -301,7 +317,8 @@ module.exports = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
limit: req.query.limit || 20,
|
||||
before: req.query.before
|
||||
before: req.query.before,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getCommits(opts).then(function(data) {
|
||||
res.json(data);
|
||||
@@ -315,7 +332,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
sha: req.params.sha
|
||||
sha: req.params.sha,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getCommit(opts).then(function(data) {
|
||||
res.json({commit:data});
|
||||
@@ -330,7 +348,8 @@ module.exports = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
remote: req.params[0],
|
||||
track: req.query.u
|
||||
track: req.query.u,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.push(opts).then(function(data) {
|
||||
res.status(204).end();
|
||||
@@ -346,7 +365,8 @@ module.exports = {
|
||||
id: req.params.id,
|
||||
remote: req.params[0],
|
||||
track: req.query.setUpstream,
|
||||
allowUnrelatedHistories: req.query.allowUnrelatedHistories
|
||||
allowUnrelatedHistories: req.query.allowUnrelatedHistories,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.pull(opts).then(function(data) {
|
||||
res.status(204).end();
|
||||
@@ -359,7 +379,8 @@ module.exports = {
|
||||
app.delete("/:id/merge", needsPermission("projects.write"), function(req, res) {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id
|
||||
id: req.params.id,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.abortMerge(opts).then(function() {
|
||||
res.status(204).end();
|
||||
@@ -374,7 +395,8 @@ module.exports = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
path: req.params[0],
|
||||
resolution: req.body.resolutions
|
||||
resolution: req.body.resolutions,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.resolveMerge(opts).then(function() {
|
||||
res.status(204).end();
|
||||
@@ -388,7 +410,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
remote: false
|
||||
remote: false,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getBranches(opts).then(function(data) {
|
||||
res.json(data);
|
||||
@@ -403,7 +426,8 @@ module.exports = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
branch: req.params.branchName,
|
||||
force: !!req.query.force
|
||||
force: !!req.query.force,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.deleteBranch(opts).then(function(data) {
|
||||
res.status(204).end();
|
||||
@@ -417,7 +441,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
remote: true
|
||||
remote: true,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getBranches(opts).then(function(data) {
|
||||
res.json(data);
|
||||
@@ -431,7 +456,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
branch: req.params[0]
|
||||
branch: req.params[0],
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.getBranchStatus(opts).then(function(data) {
|
||||
res.json(data);
|
||||
@@ -446,7 +472,8 @@ module.exports = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
branch: req.body.name,
|
||||
create: req.body.create
|
||||
create: req.body.create,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.setBranch(opts).then(function(data) {
|
||||
res.json(data);
|
||||
@@ -463,7 +490,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
remote: req.body
|
||||
remote: req.body,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
if (/^https?:\/\/[^/]+@/i.test(req.body.url)) {
|
||||
res.status(400).json({error:"unexpected_error", message:"Git http url must not include username/password"});
|
||||
@@ -481,7 +509,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
remote: req.params.remoteName
|
||||
remote: req.params.remoteName,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.removeRemote(opts).then(function(data) {
|
||||
getProjectRemotes(req,res);
|
||||
@@ -497,7 +526,8 @@ module.exports = {
|
||||
var opts = {
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
remote: remote
|
||||
remote: remote,
|
||||
req: apiUtils.getRequestLogObject(req)
|
||||
}
|
||||
runtimeAPI.projects.updateRemote(opts).then(function() {
|
||||
res.status(204).end();
|
||||
|
@@ -28,7 +28,7 @@ var defaultContext = {
|
||||
},
|
||||
header: {
|
||||
title: "Node-RED",
|
||||
image: "red/images/node-red.png"
|
||||
image: "red/images/node-red.svg"
|
||||
},
|
||||
asset: {
|
||||
red: (process.env.NODE_ENV == "development")? "red/red.js":"red/red.min.js",
|
||||
|
@@ -25,7 +25,7 @@ var theme = require("./theme");
|
||||
|
||||
var runtimeAPI;
|
||||
var editorClientDir = path.dirname(require.resolve("@node-red/editor-client"));
|
||||
var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.png");
|
||||
var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.svg");
|
||||
var editorTemplatePath = path.join(editorClientDir,"templates","index.mst");
|
||||
var editorTemplate;
|
||||
|
||||
|
@@ -42,7 +42,7 @@ var editor;
|
||||
/**
|
||||
* Initialise the module.
|
||||
* @param {Object} settings The runtime settings
|
||||
* @param {HTTPServer} server An instance of HTTP Server
|
||||
* @param {HTTPServer} _server An instance of HTTP Server
|
||||
* @param {Storage} storage An instance of Node-RED Storage
|
||||
* @param {Runtime} runtimeAPI An instance of Node-RED Runtime
|
||||
* @memberof @node-red/editor-api
|
||||
|
@@ -47,5 +47,12 @@ module.exports = {
|
||||
code: err.code||"unexpected_error",
|
||||
message: err.message||err.toString()
|
||||
});
|
||||
},
|
||||
getRequestLogObject: function(req) {
|
||||
return {
|
||||
user: req.user,
|
||||
path: req.path,
|
||||
ip: (req.headers && req.headers['x-forwarded-for']) || (req.connection && req.connection.remoteAddress) || undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@node-red/editor-api",
|
||||
"version": "1.0.0-beta.2",
|
||||
"version": "1.0.3",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
@@ -16,17 +16,17 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@node-red/util": "1.0.0-beta.2",
|
||||
"@node-red/editor-client": "1.0.0-beta.2",
|
||||
"@node-red/util": "1.0.3",
|
||||
"@node-red/editor-client": "1.0.3",
|
||||
"bcryptjs": "2.4.3",
|
||||
"body-parser": "1.19.0",
|
||||
"clone": "2.1.2",
|
||||
"cors": "2.8.5",
|
||||
"express-session": "1.16.1",
|
||||
"express": "4.17.0",
|
||||
"express-session": "1.17.0",
|
||||
"express": "4.17.1",
|
||||
"memorystore": "1.6.1",
|
||||
"mime": "2.4.3",
|
||||
"mustache": "3.0.1",
|
||||
"mime": "2.4.4",
|
||||
"mustache": "3.0.2",
|
||||
"oauth2orize": "1.11.0",
|
||||
"passport-http-bearer": "1.0.1",
|
||||
"passport-oauth2-client-password": "0.1.2",
|
||||
@@ -35,6 +35,6 @@
|
||||
"ws": "6.2.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"bcrypt": "3.0.5"
|
||||
"bcrypt": "3.0.6"
|
||||
}
|
||||
}
|
||||
|
@@ -26,8 +26,7 @@
|
||||
"status" : "Status",
|
||||
"enabled" : "Aktiviert",
|
||||
"disabled" : "Inaktiviert",
|
||||
"info" : "Beschreibung",
|
||||
"tip" : "Beschreibung akzeptiert Markdown und wird auf der Registerkarte Info angezeigt."
|
||||
"info" : "Beschreibung"
|
||||
},
|
||||
"menu" : {
|
||||
"label" : {
|
||||
@@ -237,7 +236,6 @@
|
||||
"deleteSubflow" : "Subflow löschen",
|
||||
"info" : "Beschreibung",
|
||||
"category" : "Kategorie",
|
||||
"format" : "Markdown-Format",
|
||||
"errors" : {
|
||||
"noNodesSelected" : "<strong> Subflow kann nicht erstellt werden </strong>: Es wurden keine Nodes ausgewählt.",
|
||||
"multipleInputsToSelection" : "<strong> Subflow kann nicht erstellt werden </strong>: Mehrere Eingaben zur Auswahl"
|
||||
@@ -446,8 +444,8 @@
|
||||
"none" : "keine",
|
||||
"subflows" : "Subflows",
|
||||
"flows" : "Flows",
|
||||
"filterUnused" : "Nicht verwendet",
|
||||
"filterAll" : "alle",
|
||||
"filterUnused" : "Nicht verwendet",
|
||||
"filtered" : "__count__ verdeckt"
|
||||
},
|
||||
"context" : {
|
||||
|
@@ -15,6 +15,17 @@
|
||||
"next": "Next",
|
||||
"clone": "Clone project",
|
||||
"cont": "Continue"
|
||||
},
|
||||
"type": {
|
||||
"string": "string",
|
||||
"number": "number",
|
||||
"boolean": "boolean",
|
||||
"array": "array",
|
||||
"buffer": "buffer",
|
||||
"object": "object",
|
||||
"jsonString": "JSON string",
|
||||
"undefined": "undefined",
|
||||
"null": "null"
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
@@ -310,10 +321,12 @@
|
||||
"addNewType": "Add new __type__...",
|
||||
"nodeProperties": "node properties",
|
||||
"label": "Label",
|
||||
"color": "Color",
|
||||
"portLabels": "Port labels",
|
||||
"labelInputs": "Inputs",
|
||||
"labelOutputs": "Outputs",
|
||||
"settingIcon": "Icon",
|
||||
"default": "default",
|
||||
"noDefaultLabel": "none",
|
||||
"defaultLabel": "use default label",
|
||||
"searchIcons": "Search icons",
|
||||
@@ -321,6 +334,40 @@
|
||||
"description": "Description",
|
||||
"show": "Show",
|
||||
"hide": "Hide",
|
||||
"locale": "Select UI Language",
|
||||
"icon": "Icon",
|
||||
"inputType": "Input type",
|
||||
"inputs" : {
|
||||
"input": "input",
|
||||
"select": "select",
|
||||
"checkbox": "checkbox",
|
||||
"spinner": "spinner",
|
||||
"none": "none",
|
||||
"hidden": "hide property"
|
||||
},
|
||||
"types": {
|
||||
"str": "string",
|
||||
"num": "number",
|
||||
"bool": "bool",
|
||||
"json": "JSON",
|
||||
"bin": "buffer",
|
||||
"env": "env variable"
|
||||
},
|
||||
"menu": {
|
||||
"input": "input",
|
||||
"select": "select",
|
||||
"checkbox": "checkbox",
|
||||
"spinner": "spinner",
|
||||
"hidden": "label only"
|
||||
},
|
||||
"select": {
|
||||
"label": "Label",
|
||||
"value": "Value"
|
||||
},
|
||||
"spinner": {
|
||||
"min": "Minimum",
|
||||
"max": "Maximum"
|
||||
},
|
||||
"errors": {
|
||||
"scopeChange": "Changing the scope will make it unavailable to nodes in other flows that use it",
|
||||
"invalidProperties": "Invalid properties:"
|
||||
@@ -351,7 +398,8 @@
|
||||
"pasteNode": "Paste nodes",
|
||||
"undoChange": "Undo the last change performed",
|
||||
"searchBox": "Open search box",
|
||||
"managePalette": "Manage palette"
|
||||
"managePalette": "Manage palette",
|
||||
"actionList":"Action list"
|
||||
},
|
||||
"library": {
|
||||
"library": "Library",
|
||||
@@ -365,6 +413,7 @@
|
||||
"savedNodes": "Saved nodes",
|
||||
"savedType": "Saved __type__",
|
||||
"saveFailed": "Save failed: __message__",
|
||||
"newFolder": "New folder",
|
||||
"types": {
|
||||
"local": "Local",
|
||||
"examples": "Examples"
|
||||
@@ -377,9 +426,13 @@
|
||||
"addCategory": "Add new...",
|
||||
"label": {
|
||||
"subflows": "subflows",
|
||||
"network": "network",
|
||||
"common": "common",
|
||||
"input": "input",
|
||||
"output": "output",
|
||||
"function": "function",
|
||||
"sequence": "sequence",
|
||||
"parser": "parser",
|
||||
"social": "social",
|
||||
"storage": "storage",
|
||||
"analysis": "analysis",
|
||||
@@ -516,8 +569,10 @@
|
||||
"none": "none",
|
||||
"subflows": "subflows",
|
||||
"flows": "flows",
|
||||
"filterUnused":"unused",
|
||||
"filterAll":"all",
|
||||
"filterAll": "all",
|
||||
"showAllConfigNodes": "Show all config nodes",
|
||||
"filterUnused": "unused",
|
||||
"showAllUnusedConfigNodes": "Show all unused config nodes",
|
||||
"filtered": "__count__ hidden"
|
||||
},
|
||||
"context": {
|
||||
@@ -530,7 +585,9 @@
|
||||
"flow": "Flow",
|
||||
"global": "Global",
|
||||
"deleteConfirm": "Are you sure you want to delete this item?",
|
||||
"autoRefresh": "Auto-refresh"
|
||||
"autoRefresh": "Refresh on selection change",
|
||||
"refrsh": "Refresh",
|
||||
"delete": "Delete"
|
||||
},
|
||||
"palette": {
|
||||
"name": "Palette management",
|
||||
@@ -545,6 +602,7 @@
|
||||
"noSummaryAvailable": "No summary available",
|
||||
"editDescription": "Edit project description",
|
||||
"editDependencies": "Edit project dependencies",
|
||||
"noDescriptionAvailable": "No description available",
|
||||
"editReadme": "Edit README.md",
|
||||
"showProjectSettings": "Show project settings",
|
||||
"projectSettings": {
|
||||
@@ -736,10 +794,23 @@
|
||||
},
|
||||
"jsonEditor": {
|
||||
"title": "JSON editor",
|
||||
"format": "format JSON"
|
||||
"format": "format JSON",
|
||||
"rawMode": "Edit JSON",
|
||||
"uiMode": "Visual editor",
|
||||
"insertAbove": "Insert above",
|
||||
"insertBelow": "Insert below",
|
||||
"addItem": "Add item",
|
||||
"copyPath": "Copy path to item",
|
||||
"expandItems": "Expand items",
|
||||
"collapseItems": "Collapse items",
|
||||
"duplicate": "Duplicate",
|
||||
"error": {
|
||||
"invalidJSON": "Invalid JSON: "
|
||||
}
|
||||
},
|
||||
"markdownEditor": {
|
||||
"title": "Markdown editor",
|
||||
"expand": "Expand",
|
||||
"format": "Formatted with markdown",
|
||||
"heading1": "Heading 1",
|
||||
"heading2": "Heading 2",
|
||||
@@ -926,8 +997,17 @@
|
||||
},
|
||||
"editor-tab": {
|
||||
"properties": "Properties",
|
||||
"envProperties": "Environment Variables",
|
||||
"description": "Description",
|
||||
"appearance": "Appearance",
|
||||
"env": "Environment Variables"
|
||||
"preview": "UI Preview",
|
||||
"defaultValue": "Default value"
|
||||
},
|
||||
"languages" : {
|
||||
"de": "German",
|
||||
"en-US": "English",
|
||||
"ja": "Japanese",
|
||||
"ko": "Korean",
|
||||
"zh-CN": "Chinese(Simplified)"
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$string": {
|
||||
"args": "arg",
|
||||
"desc": "Casts the *arg* parameter to a string using the following casting rules:\n\n - Strings are unchanged\n - Functions are converted to an empty string\n - Numeric infinity and NaN throw an error because they cannot be represented as a JSON number\n - All other values are converted to a JSON string using the `JSON.stringify` function"
|
||||
"args": "arg[, prettify]",
|
||||
"desc": "Casts the `arg` parameter to a string using the following casting rules:\n\n - Strings are unchanged\n - Functions are converted to an empty string\n - Numeric infinity and NaN throw an error because they cannot be represented as a JSON number\n - All other values are converted to a JSON string using the `JSON.stringify` function. If `prettify` is true, then \"prettified\" JSON is produced. i.e One line per field and lines will be indented based on the field depth."
|
||||
},
|
||||
"$length": {
|
||||
"args": "str",
|
||||
@@ -185,7 +185,7 @@
|
||||
},
|
||||
"$reduce": {
|
||||
"args":"array, function [, init]",
|
||||
"desc":"Returns an aggregated value derived from applying the `function` parameter successively to each value in `array` in combination with the result of the previous application of the function.\n\nThe function must accept two arguments, and behaves like an infix operator between each value within the `array`.\n\nThe optional `init` parameter is used as the initial value in the aggregation."
|
||||
"desc":"Returns an aggregated value derived from applying the `function` parameter successively to each value in `array` in combination with the result of the previous application of the function.\n\nThe function must accept two arguments, and behaves like an infix operator between each value within the `array`. The signature of `function` must be of the form: `myfunc($accumulator, $value[, $index[, $array]])`\n\nThe optional `init` parameter is used as the initial value in the aggregation."
|
||||
},
|
||||
"$flowContext": {
|
||||
"args": "string[, string]",
|
||||
@@ -230,6 +230,37 @@
|
||||
"$parseInteger": {
|
||||
"args": "string, picture",
|
||||
"desc": "Parses the contents of the `string` parameter to an integer (as a JSON number) using the format specified by the `picture` string. The `picture` string parameter has the same format as `$formatInteger`."
|
||||
|
||||
},
|
||||
"$error": {
|
||||
"args": "[str]",
|
||||
"desc": "Throws an error with a message. The optional `str` will replace the default message of `$error() function evaluated`"
|
||||
},
|
||||
"$assert": {
|
||||
"args": "arg, str",
|
||||
"desc": "If `arg` is true the function returns undefined. If `arg` is false an exception is thrown with `str` as the message of the exception."
|
||||
},
|
||||
"$single": {
|
||||
"args": "array, function",
|
||||
"desc": "Returns the one and only value in the `array` parameter that satisfies the `function` predicate (i.e. the `function` returns Boolean `true` when passed the value). Throws an exception if the number of matching values is not exactly one.\n\nThe function should be supplied in the following signature: `function(value [, index [, array]])` where value is each input of the array, index is the position of that value and the whole array is passed as the third argument"
|
||||
},
|
||||
"$encodeUrl": {
|
||||
"args": "str",
|
||||
"desc": "Encodes a Uniform Resource Locator (URL) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.\n\nExample: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||
},
|
||||
"$encodeUrlComponent": {
|
||||
"args": "str",
|
||||
"desc": "Encodes a Uniform Resource Locator (URL) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character. \n\nExample: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
||||
},
|
||||
"$decodeUrl": {
|
||||
"args": "str",
|
||||
"desc": "Decodes a Uniform Resource Locator (URL) component previously created by encodeUrlComponent. \n\nExample: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
||||
},
|
||||
"$decodeUrlComponent": {
|
||||
"args": "str",
|
||||
"desc": "Decodes a Uniform Resource Locator (URL) previously created by encodeUrl. \n\nExample: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
||||
},
|
||||
"$distinct": {
|
||||
"args": "array",
|
||||
"desc": "Returns an array with duplicate values removed from `array`"
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,17 @@
|
||||
"next": "進む",
|
||||
"clone": "プロジェクトをクローン",
|
||||
"cont": "続ける"
|
||||
},
|
||||
"type": {
|
||||
"string": "文字列",
|
||||
"number": "数値",
|
||||
"boolean": "真偽値",
|
||||
"array": "配列",
|
||||
"buffer": "バッファ",
|
||||
"object": "オブジェクト",
|
||||
"jsonString": "JSON文字列",
|
||||
"undefined": "undefined",
|
||||
"null": "null"
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
@@ -28,7 +39,8 @@
|
||||
"status": "状態",
|
||||
"enabled": "有効",
|
||||
"disabled": "無効",
|
||||
"info": "詳細"
|
||||
"info": "詳細",
|
||||
"selectNodes": "ノードをクリックして選択"
|
||||
},
|
||||
"menu": {
|
||||
"label": {
|
||||
@@ -42,7 +54,9 @@
|
||||
"defaultDir": "標準",
|
||||
"ltr": "左から右",
|
||||
"rtl": "右から左",
|
||||
"auto": "文脈"
|
||||
"auto": "文脈",
|
||||
"language": "表示言語",
|
||||
"browserDefault": "ブラウザのデフォルト"
|
||||
},
|
||||
"sidebar": {
|
||||
"show": "サイドバーを表示"
|
||||
@@ -77,7 +91,7 @@
|
||||
"projects-new": "新規",
|
||||
"projects-open": "開く",
|
||||
"projects-settings": "設定",
|
||||
"showNodeLabelDefault": "追加したノードのラベルを表示する"
|
||||
"showNodeLabelDefault": "追加したノードのラベルを表示"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
@@ -179,7 +193,11 @@
|
||||
"all": "全てのタブ",
|
||||
"compact": "インデントのないJSONフォーマット",
|
||||
"formatted": "インデント付きのJSONフォーマット",
|
||||
"copy": "書き出し"
|
||||
"copy": "書き出し",
|
||||
"export": "ライブラリに書き出し",
|
||||
"exportAs": "書き出し先",
|
||||
"overwrite": "更新",
|
||||
"exists": "<p><b>\"__file__\"</b>は既に存在します。</p><p>更新しますか?</p>"
|
||||
},
|
||||
"import": {
|
||||
"import": "読み込み先",
|
||||
@@ -303,10 +321,12 @@
|
||||
"addNewType": "新規に __type__ を追加...",
|
||||
"nodeProperties": "プロパティ",
|
||||
"label": "ラベル",
|
||||
"color": "色",
|
||||
"portLabels": "ポートラベル",
|
||||
"labelInputs": "入力",
|
||||
"labelOutputs": "出力",
|
||||
"settingIcon": "アイコン",
|
||||
"default": "デフォルト",
|
||||
"noDefaultLabel": "なし",
|
||||
"defaultLabel": "既定のラベルを使用",
|
||||
"searchIcons": "アイコンを検索",
|
||||
@@ -314,8 +334,43 @@
|
||||
"description": "詳細",
|
||||
"show": "表示",
|
||||
"hide": "非表示",
|
||||
"locale": "UI言語の選択",
|
||||
"icon": "記号",
|
||||
"inputType": "入力形式",
|
||||
"inputs": {
|
||||
"input": "入力",
|
||||
"select": "メニュー",
|
||||
"checkbox": "チェックボックス",
|
||||
"spinner": "スピナー",
|
||||
"none": "無し",
|
||||
"hidden": "非表示"
|
||||
},
|
||||
"types": {
|
||||
"str": "文字列",
|
||||
"num": "数値",
|
||||
"bool": "真偽",
|
||||
"json": "JSON",
|
||||
"bin": "バッファ",
|
||||
"env": "環境変数"
|
||||
},
|
||||
"menu": {
|
||||
"input": "入力",
|
||||
"select": "選択",
|
||||
"checkbox": "チェックボックス",
|
||||
"spinner": "数値",
|
||||
"hidden": "ラベルのみ"
|
||||
},
|
||||
"select": {
|
||||
"label": "ラベル",
|
||||
"value": "値"
|
||||
},
|
||||
"spinner": {
|
||||
"min": "最小値",
|
||||
"max": "最大値"
|
||||
},
|
||||
"errors": {
|
||||
"scopeChange": "スコープの変更は、他のフローで使われているノードを無効にします"
|
||||
"scopeChange": "スコープの変更は、他のフローで使われているノードを無効にします",
|
||||
"invalidProperties": "プロパティが不正です:"
|
||||
}
|
||||
},
|
||||
"keyboard": {
|
||||
@@ -343,7 +398,8 @@
|
||||
"pasteNode": "ノードを貼り付け",
|
||||
"undoChange": "変更操作を戻す",
|
||||
"searchBox": "ノードを検索",
|
||||
"managePalette": "パレットの管理"
|
||||
"managePalette": "パレットの管理",
|
||||
"actionList": "動作一覧"
|
||||
},
|
||||
"library": {
|
||||
"library": "ライブラリ",
|
||||
@@ -351,12 +407,15 @@
|
||||
"saveToLibrary": "ライブラリへ保存",
|
||||
"typeLibrary": "__type__ ライブラリ",
|
||||
"unnamedType": "名前なし __type__",
|
||||
"exportedToLibrary": "ライブラリにノードを書き出しました",
|
||||
"dialogSaveOverwrite": "__libraryName__ という __libraryType__ は既に存在しています 上書きしますか?",
|
||||
"invalidFilename": "不正なファイル名",
|
||||
"savedNodes": "フローを保存しました",
|
||||
"savedType": "__type__ を保存しました",
|
||||
"saveFailed": "保存に失敗しました: __message__",
|
||||
"newFolder": "新規フォルダ",
|
||||
"types": {
|
||||
"local": "ローカル",
|
||||
"examples": "サンプル"
|
||||
}
|
||||
},
|
||||
@@ -367,9 +426,13 @@
|
||||
"addCategory": "新規追加...",
|
||||
"label": {
|
||||
"subflows": "サブフロー",
|
||||
"network": "ネットワーク",
|
||||
"common": "共通",
|
||||
"input": "入力",
|
||||
"output": "出力",
|
||||
"function": "機能",
|
||||
"sequence": "シーケンス",
|
||||
"parser": "パーサ",
|
||||
"social": "ソーシャル",
|
||||
"storage": "ストレージ",
|
||||
"analysis": "分析",
|
||||
@@ -506,8 +569,10 @@
|
||||
"none": "なし",
|
||||
"subflows": "サブフロー",
|
||||
"flows": "フロー",
|
||||
"filterUnused": "未使用",
|
||||
"filterAll": "全て",
|
||||
"showAllConfigNodes": "全設定ノードを表示",
|
||||
"filterUnused": "未使用",
|
||||
"showAllUnusedConfigNodes": "未使用の全設定ノードを表示",
|
||||
"filtered": "__count__ 個が無効"
|
||||
},
|
||||
"context": {
|
||||
@@ -516,10 +581,13 @@
|
||||
"none": "選択されていません",
|
||||
"refresh": "読み込みのため更新してください",
|
||||
"empty": "データが存在しません",
|
||||
"node": "Node",
|
||||
"flow": "Flow",
|
||||
"global": "Global",
|
||||
"deleteConfirm": "データを削除しても良いですか?"
|
||||
"node": "ノード",
|
||||
"flow": "フロー",
|
||||
"global": "グローバル",
|
||||
"deleteConfirm": "データを削除しても良いですか?",
|
||||
"autoRefresh": "選択対象が変化した場合更新",
|
||||
"refrsh": "更新",
|
||||
"delete": "削除"
|
||||
},
|
||||
"palette": {
|
||||
"name": "パレットの管理",
|
||||
@@ -531,9 +599,10 @@
|
||||
"description": "詳細",
|
||||
"dependencies": "依存関係",
|
||||
"settings": "設定",
|
||||
"noSummaryAvailable": "サマリが存在しません",
|
||||
"noSummaryAvailable": "要約が存在しません",
|
||||
"editDescription": "プロジェクトの詳細を編集",
|
||||
"editDependencies": "プロジェクトの依存関係を編集",
|
||||
"noDescriptionAvailable": "詳細が存在しません",
|
||||
"editReadme": "README.mdを編集",
|
||||
"showProjectSettings": "プロジェクト設定を表示",
|
||||
"projectSettings": {
|
||||
@@ -719,12 +788,28 @@
|
||||
"jsEditor": {
|
||||
"title": "JavaScriptエディタ"
|
||||
},
|
||||
"textEditor": {
|
||||
"title": "テキストエディタ"
|
||||
},
|
||||
"jsonEditor": {
|
||||
"title": "JSONエディタ",
|
||||
"format": "JSONフォーマット"
|
||||
"format": "JSONフォーマット",
|
||||
"rawMode": "JSONを編集",
|
||||
"uiMode": "ビジュアルエディタ",
|
||||
"insertAbove": "上に挿入",
|
||||
"insertBelow": "下に挿入",
|
||||
"addItem": "要素を追加",
|
||||
"copyPath": "要素のパスをコピー",
|
||||
"expandItems": "要素を展開",
|
||||
"collapseItems": "要素を折り畳む",
|
||||
"duplicate": "複製",
|
||||
"error": {
|
||||
"invalidJSON": "不正なJSON: "
|
||||
}
|
||||
},
|
||||
"markdownEditor": {
|
||||
"title": "マークダウンエディタ",
|
||||
"expand": "拡大",
|
||||
"format": "マークダウン形式で記述",
|
||||
"heading1": "見出しレベル1",
|
||||
"heading2": "見出しレベル2",
|
||||
@@ -885,7 +970,7 @@
|
||||
"confirm": "<p>デプロイされていない変更は失われます。</p><p>続けますか?</p>"
|
||||
},
|
||||
"send-req": {
|
||||
"auth-req": "リポジトリ対する認証が必要です",
|
||||
"auth-req": "リポジトリに対する認証が必要です",
|
||||
"username": "ユーザ名",
|
||||
"password": "パスワード",
|
||||
"passphrase": "パスフレーズ",
|
||||
@@ -911,8 +996,17 @@
|
||||
},
|
||||
"editor-tab": {
|
||||
"properties": "プロパティ",
|
||||
"envProperties": "環境変数",
|
||||
"description": "説明",
|
||||
"appearance": "外観",
|
||||
"env": "環境変数"
|
||||
"preview": "UIプレビュー",
|
||||
"defaultValue": "デフォルト値"
|
||||
},
|
||||
"languages": {
|
||||
"de": "ドイツ語",
|
||||
"en-US": "英語",
|
||||
"ja": "日本語",
|
||||
"ko": "韓国語",
|
||||
"zh-CN": "中国語(簡体)"
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$string": {
|
||||
"args": "arg",
|
||||
"desc": "以下の型変換ルールを用いて、引数 *arg* を文字列へ型変換します。:\n\n - 文字列は変換しません。\n - 関数は空の文字列に変換します。\n - JSONの数値として表現できないため、無限大やNaNはエラーになります。\n - 他の値は `JSON.stringify` 関数を用いて、JSONの文字列へ変換します。"
|
||||
"args": "arg[, prettify]",
|
||||
"desc": "以下の型変換ルールを用いて、引数 *arg* を文字列へ型変換します。:\n\n - 文字列は変換しません。\n - 関数は空の文字列に変換します。\n - JSONの数値として表現できないため、無限大やNaNはエラーになります。\n - 他の値は `JSON.stringify` 関数を用いて、JSONの文字列へ変換します。`prettify`が真の場合、JSONを整形出力します。フィールドを1行毎に出力。フィールドのネスト深さによってインデントを行います。"
|
||||
},
|
||||
"$length": {
|
||||
"args": "str",
|
||||
@@ -185,7 +185,7 @@
|
||||
},
|
||||
"$reduce": {
|
||||
"args": "array, function [, init]",
|
||||
"desc": "配列の各要素値に関数 `function` を連続的に適用して得られる集約値を返します。 `function` の適用の際には、直前の `function` の適用結果と要素値が引数として与えられます。\n\n関数 `function` は引数を2つ取り、配列の各要素の間に配置する中置演算子のように作用しなくてはなりません。\n\n任意の引数 `init` には、集約時の初期値を設定します。"
|
||||
"desc": "配列の各要素値に関数 `function` を連続的に適用して得られる集約値を返します。 `function` の適用の際には、直前の `function` の適用結果と要素値が引数として与えられます。\n\n関数 `function` は引数を2つ取り、配列の各要素の間に配置する中置演算子のように作用しなくてはなりません。関数`function`のシグネチャは`myfunc($accumulator, $value[, $index[, $array]])`という形式でなければなりません。\n\n任意の引数 `init` には、集約時の初期値を設定します。"
|
||||
},
|
||||
"$flowContext": {
|
||||
"args": "string",
|
||||
@@ -230,5 +230,37 @@
|
||||
"$parseInteger": {
|
||||
"args": "string, picture",
|
||||
"desc": "`picture`文字列の指定に従って、`string`パラメータを整数(JSON数値)に変換します。`picture`文字列は`$formatInteger`と同じ形式です。"
|
||||
},
|
||||
"$error": {
|
||||
"args": "[str]",
|
||||
"desc": "メッセージを指定して例外を送出します。メッセージ`str`を省略した場合は`$error() function evaluated`をメッセージとします。"
|
||||
},
|
||||
"$assert": {
|
||||
"args": "arg, str",
|
||||
"desc": "`arg`が真の場合、undefinedを返します。偽の場合、`str`をメッセージとする例外を送出します。"
|
||||
},
|
||||
"$single": {
|
||||
"args": "array, function",
|
||||
"desc": "`array`の要素のうち、条件判定関数`function`を満たす(`function`に与えた場合に真偽値`true`を返す)要素が1つのみである場合、それを返します。マッチする要素が1つのみでない場合、例外を送出します。\n\n指定する関数は`function(value [, index [, array]])`というシグネチャでなければなりません。ここで、`value`は`array`の要素値、`index`は要素の添字、第三引数には配列全体を渡します。"
|
||||
},
|
||||
"$encodeUrl": {
|
||||
"args": "str",
|
||||
"desc": "Uniform Resource Locator (URL)を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||
},
|
||||
"$encodeUrlComponent": {
|
||||
"args": "str",
|
||||
"desc": "Uniform Resource Locator (URL)要素を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
||||
},
|
||||
"$decodeUrl": {
|
||||
"args": "str",
|
||||
"desc": "encodeUrlComponentで置換したUniform Resource Locator (URL)をデコードします。\n\n例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
||||
},
|
||||
"$decodeUrlComponent": {
|
||||
"args": "str",
|
||||
"desc": "encodeUrlで置換したUniform Resource Locator (URL)要素をデコードします。 \n\n例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
||||
},
|
||||
"$distinct": {
|
||||
"args": "array",
|
||||
"desc": "配列`array`から重複要素を削除した配列を返します。"
|
||||
}
|
||||
}
|
||||
|
@@ -273,7 +273,6 @@
|
||||
"deleteSubflow": "서브 플로우 삭제",
|
||||
"info": "상세내역",
|
||||
"category": "카테고리",
|
||||
"format": "Markdown 형식",
|
||||
"errors": {
|
||||
"noNodesSelected": "<strong>서브 플로우를 생성할 수 없습니다</strong> : 노드가 선택되지 않았습니다",
|
||||
"multipleInputsToSelection": "<strong>서브 플로우를 생성할 수 없습니다</strong> : 복수의 입력이 선택되었습니다"
|
||||
@@ -495,8 +494,8 @@
|
||||
"none": "없음",
|
||||
"subflows": "보조 플로우",
|
||||
"flows": "플로우",
|
||||
"filterUnused": "미사용",
|
||||
"filterAll": "전체",
|
||||
"filterUnused": "미사용",
|
||||
"filtered": "__count__ 개 숨김"
|
||||
},
|
||||
"context": {
|
||||
|
@@ -385,8 +385,8 @@
|
||||
"none": "无",
|
||||
"subflows": "子流程",
|
||||
"flows": "流程",
|
||||
"filterUnused": "未使用",
|
||||
"filterAll": "所有",
|
||||
"filterUnused": "未使用",
|
||||
"filtered": "__count__ 个隐藏"
|
||||
},
|
||||
"palette": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@node-red/editor-client",
|
||||
"version": "1.0.0-beta.2",
|
||||
"version": "1.0.3",
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
Before Width: | Height: | Size: 291 B |
1
packages/node_modules/@node-red/editor-client/src/images/deploy-flows-o.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="27" height="18" xmlns="http://www.w3.org/2000/svg"><g color="#000"><path fill="#fff" d="M0 5.002h10v5H0zM17 .002h10v5H17z"/><path d="M17 13.002h10v5H17z"/></g><path d="M9.5 7.502h2l4-5h2" fill="none" stroke="#fff" stroke-width="1.5"/></svg>
|
After Width: | Height: | Size: 252 B |
Before Width: | Height: | Size: 386 B |
1
packages/node_modules/@node-red/editor-client/src/images/deploy-flows.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><path color="#000" fill="#8c101c" d="M0 .002h32v32H0z"/><g color="#000"><path fill="#fff" d="M2 13.002h10v5H2zM19 8.002h10v5H19z"/><path d="M19 21.002h10v5H19z"/></g><path d="M11.5 15.502h2l4-5h2" fill="none" stroke="#fff" stroke-width="1.5"/></svg>
|
After Width: | Height: | Size: 312 B |
Before Width: | Height: | Size: 289 B |
1
packages/node_modules/@node-red/editor-client/src/images/deploy-full-o.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="27" height="18" xmlns="http://www.w3.org/2000/svg"><g fill="#fff" color="#000"><path d="M0 5h10v5H0zM17 0h10v5H17zM17 13h10v5H17z"/></g><path d="M9.5 7.5h2l4-5h2" fill="none" stroke="#fff" stroke-width="1.5"/></svg>
|
After Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 368 B |
1
packages/node_modules/@node-red/editor-client/src/images/deploy-full.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><path color="#000" fill="#8c101c" d="M0 0h32v32H0z"/><g fill="#fff" color="#000"><path d="M2 13h10v5H2zM19 8h10v5H19zM19 21h10v5H19z"/></g><path d="M11.5 15.5h2l4-5h2" fill="none" stroke="#fff" stroke-width="1.5"/></svg>
|
After Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 290 B |
1
packages/node_modules/@node-red/editor-client/src/images/deploy-nodes-o.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="27" height="18" xmlns="http://www.w3.org/2000/svg"><path color="#000" d="M0 5.002h10v5H0zM17 13.002h10v5H17z"/><path d="M9.5 7.502h2l4-5h2" fill="none" stroke="#000" stroke-width="1.5"/><path color="#000" fill="#fff" d="M17 .002h10v5H17z"/></svg>
|
After Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 392 B |
1
packages/node_modules/@node-red/editor-client/src/images/deploy-nodes.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><path color="#000" fill="#8c101c" d="M0 .002h32v32H0z"/><path color="#000" d="M2 13.002h10v5H2zM19 21.002h10v5H19z"/><path d="M11.5 15.502h2l4-5h2" fill="none" stroke="#000" stroke-width="1.5"/><path color="#000" fill="#fff" d="M19 8.002h10v5H19z"/></svg>
|
After Width: | Height: | Size: 318 B |
Before Width: | Height: | Size: 1015 B |
1
packages/node_modules/@node-red/editor-client/src/images/deploy-reload.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><g color="#000"><path fill="#8c101c" d="M0 .006h32v32H0z"/><path d="M11.81 25.429a10.02 10.02 0 0 0 4.19.914c5.562 0 10.107-4.545 10.107-10.106S21.562 6.131 16 6.131 5.895 10.676 5.895 16.237h3.368c0-3.74 2.997-6.737 6.738-6.737s6.737 2.996 6.737 6.737-2.996 6.738-6.737 6.738a6.775 6.775 0 0 1-2.533-.486l1.43-3.48-6.947 1.317 2.13 8.485z" fill="#fff" style="isolation:auto;mix-blend-mode:normal;text-decoration-color:#000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/></g></svg>
|
After Width: | Height: | Size: 606 B |
Before Width: | Height: | Size: 393 B |
1
packages/node_modules/@node-red/editor-client/src/images/icons/arrow-in.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="40" height="60" viewBox="0, 0, 40, 60" xmlns="http://www.w3.org/2000/svg"><path d="M18 5v12H7v26h11v12l14-25z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 143 B |
Before Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 1019 B |
1
packages/node_modules/@node-red/editor-client/src/images/node-red.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="46.994" height="18.006" xmlns="http://www.w3.org/2000/svg"><g stroke="#d6d6d6"><g fill="#9e3131" stroke-linejoin="round" stroke-width="3.847" transform="matrix(.25848 0 0 .2614 -63.87 -108.483)"><rect x="249.04" y="435.92" width="50.294" height="22.953" ry="6.608"/><rect x="345.63" y="416.93" width="50.294" height="22.953" ry="6.608"/><rect x="376.71" y="459.01" width="50.294" height="22.953" ry="6.608"/></g><path d="M301.04 447.43c24.406.184 7.107-18.84 42.708-19.03M374.82 470.48c-46.966.538-28.989-22.664-73.619-22.944" fill="none" stroke-width="5.771" transform="matrix(.25848 0 0 .2614 -63.87 -108.483)"/></g></svg>
|
After Width: | Height: | Size: 636 B |
Before Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 410 B |
1
packages/node_modules/@node-red/editor-client/src/images/subflow_tab.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="40" height="40" viewBox="0, 0, 40, 40" xmlns="http://www.w3.org/2000/svg"><path d="M25 16h7c.58 0 1-.42 1-1v-2c0-.58-.42-1-1-1h-7c-.58 0-1 .42-1 1v2c0 .58.42 1 1 1zM8 28h7c.58 0 1-.42 1-1v-2c0-.58-.42-1-1-1H8c-.58 0-1 .42-1 1v2c0 .58.42 1 1 1zm-.416 11C5.624 39 4 37.375 4 35.416V4.582C4 2.622 5.625 1 7.584 1h24.832C34.376 1 36 2.623 36 4.582v30.834C36 37.376 34.375 39 32.416 39zM32 27H19c0 2.19-1.81 4-4 4H7v4.416c0 .35.235.584.584.584h24.832c.35 0 .584-.235.584-.584v-8.417zm1-2v-6h-8c-2.19 0-4-1.81-4-4h-1c-4.333-.002-8.667.004-13 0v6h8c2.19 0 4 1.81 4 4h13zm0-16V4.582c0-.35-.235-.582-.584-.582H7.584C7.234 4 7 4.233 7 4.582v8.417c4.333.002 8.667.001 13 .001h1c0-2.19 1.81-4 4-4z" color="#000" fill="#333"/></svg>
|
After Width: | Height: | Size: 732 B |
Before Width: | Height: | Size: 638 B |
1
packages/node_modules/@node-red/editor-client/src/images/typedInput/09.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="26" height="36" viewBox="0, 0, 26, 36" xmlns="http://www.w3.org/2000/svg"><path d="M14.16 27.38l1.555-.144c.132.731.383 1.261.755 1.591.371.33.848.494 1.429.494.497 0 .931-.114 1.303-.341.377-.228.686-.53.926-.908.24-.383.44-.899.602-1.546a8.122 8.122 0 0 0 .233-2.3 3.732 3.732 0 0 1-1.33 1.258 3.605 3.605 0 0 1-1.815.476c-1.09 0-2.013-.395-2.768-1.186s-1.133-1.834-1.133-3.128c0-1.336.393-2.411 1.178-3.226.79-.815 1.78-1.223 2.966-1.223.856 0 1.638.231 2.345.692.713.462 1.253 1.12 1.618 1.978.372.85.557 2.085.557 3.702 0 1.684-.182 3.026-.548 4.027-.365.994-.91 1.752-1.636 2.274-.719.52-1.563.781-2.534.781-1.03 0-1.872-.284-2.525-.853-.654-.576-1.046-1.381-1.178-2.418zm6.624-5.815c0-.928-.249-1.666-.746-2.21-.492-.546-1.085-.819-1.78-.819-.719 0-1.345.294-1.878.881s-.8 1.348-.8 2.283c0 .839.252 1.522.755 2.05.51.52 1.135.781 1.878.781.75 0 1.363-.26 1.843-.782.485-.527.728-1.255.728-2.184zM4.858 10.466c0-1.558.158-2.81.476-3.757.324-.952.8-1.686 1.429-2.201.635-.516 1.432-.773 2.39-.773.708 0 1.328.143 1.861.431.533.282.974.692 1.321 1.231.348.534.62 1.187.818 1.96.198.767.297 1.803.297 3.11 0 1.545-.16 2.794-.477 3.747-.317.947-.794 1.68-1.429 2.202-.629.515-1.426.773-2.39.773-1.27 0-2.268-.456-2.993-1.366-.869-1.097-1.303-2.882-1.303-5.357zm1.662 0c0 2.163.252 3.604.755 4.323.51.713 1.136 1.07 1.879 1.07.743 0 1.366-.36 1.87-1.079.508-.719.763-2.157.763-4.314 0-2.169-.255-3.61-.764-4.323-.503-.713-1.132-1.07-1.887-1.07-.743 0-1.336.315-1.78.944-.557.803-.836 2.286-.836 4.45z" fill="#444"/></svg>
|
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 546 B |
1
packages/node_modules/@node-red/editor-client/src/images/typedInput/az.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="26" height="36" viewBox="0, 0, 26, 36" xmlns="http://www.w3.org/2000/svg"><path d="M13.27 29.15l6.733-8.143h-6.235V19.3h8.8v1.559l-6.69 8.09h6.892v1.707h-9.5zm4.909-10.125zM6.577 12.58q0 .827.604 1.304.605.478 1.432.478 1.007 0 1.95-.467 1.59-.774 1.59-2.534V9.824q-.349.222-.9.37-.552.15-1.082.213l-1.155.148q-1.04.138-1.56.435-.88.498-.88 1.59zM11.2 8.721q.657-.085.88-.551.127-.255.127-.732 0-.975-.7-1.41-.689-.445-1.983-.445-1.495 0-2.12.805-.35.446-.456 1.326H5.167q.053-2.1 1.357-2.916 1.315-.827 3.043-.827 2.004 0 3.255.763 1.24.764 1.24 2.375v6.542q0 .297.117.477.127.18.52.18.127 0 .286-.01.159-.021.34-.053v1.41q-.446.127-.68.16-.233.031-.636.031-.986 0-1.43-.7-.234-.37-.33-1.05-.583.764-1.675 1.326t-2.407.562q-1.58 0-2.587-.954-.996-.965-.996-2.407 0-1.58.986-2.45.986-.869 2.587-1.07zm-1.58-4.75z" fill="#444"/></svg>
|
After Width: | Height: | Size: 846 B |
Before Width: | Height: | Size: 638 B |
1
packages/node_modules/@node-red/editor-client/src/images/typedInput/bin.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="26" height="36" viewBox="0, 0, 26, 36" xmlns="http://www.w3.org/2000/svg"><path d="M18.8 33.9c3.328 0 4.776-2.603 4.776-7.066s-1.448-7.066-4.776-7.066-4.776 2.603-4.776 7.066S15.473 33.9 18.8 33.9zm0-1.429c-2.192 0-3.073-1.781-3.073-4.522v-2.23c0-2.741.88-4.523 3.073-4.523s3.073 1.782 3.073 4.522v2.231c0 2.74-.88 4.522-3.073 4.522zm-6.306 1.194v-1.429H8.892V20.002H6.328l-3.621 3.386.959 1.038 3.445-3.21h.137v11.02H3.333v1.429zm11.2-17.7v-1.429h-3.602V2.302h-2.564l-3.621 3.386.959 1.038 3.445-3.21h.137v11.02h-3.915v1.429zM7.5 16.2c3.327 0 4.776-2.603 4.776-7.066S10.828 2.068 7.5 2.068 2.725 4.67 2.725 9.134 4.173 16.2 7.5 16.2zm0-1.429c-2.193 0-3.074-1.781-3.074-4.522V8.02c0-2.741.881-4.523 3.074-4.523s3.073 1.782 3.073 4.522v2.231c0 2.74-.881 4.522-3.073 4.522z" fill="#444"/></svg>
|
After Width: | Height: | Size: 805 B |
Before Width: | Height: | Size: 646 B |
1
packages/node_modules/@node-red/editor-client/src/images/typedInput/bool.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="26" height="36" viewBox="0, 0, 26, 36" xmlns="http://www.w3.org/2000/svg"><path d="M9.96 21.98a5 5 0 1 1 6.11-7.917zm3.035-13.973c-5.512 0-10 4.488-10 10s4.488 9.998 10 9.998 10-4.486 10-9.998-4.488-10-10-10zm0 1.816c4.53 0 8.182 3.655 8.182 8.184s-3.652 8.182-8.182 8.182-8.181-3.653-8.181-8.182 3.652-8.184 8.181-8.184z" color="#000" fill="#444"/></svg>
|
After Width: | Height: | Size: 368 B |
Before Width: | Height: | Size: 809 B |
1
packages/node_modules/@node-red/editor-client/src/images/typedInput/env.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="26" height="36" viewBox="0, 0, 26, 36" xmlns="http://www.w3.org/2000/svg"><path d="M14.33 27.19q2.916-.136 4.024-2.131.58-1.024.58-2.37 0-2.132-1.569-3.24-.904-.648-3.035-1.228zM8.55 10.736q0 1.688 1.108 2.643 1.125.955 3.018 1.33V6.695q-2.234.085-3.189 1.364-.937 1.279-.937 2.677zm-3.07.205q0-2.592 1.893-4.672 1.91-2.08 5.337-2.115V1.887h1.62V4.12q3.393.239 5.2 2.012 1.825 1.757 1.91 4.655h-2.984q-.119-1.296-.699-2.233-1.074-1.723-3.427-1.808v8.287q3.956 1.108 5.371 2.08 2.302 1.603 2.302 4.74 0 4.536-2.95 6.446-1.637 1.057-4.723 1.398v3.308h-1.62v-3.308q-4.962-.324-6.735-3.513-.972-1.722-.972-4.655h3.018q.136 2.336.733 3.41 1.057 1.927 3.922 2.166v-9.293q-3.683-.699-5.44-2.336Q5.48 13.84 5.48 10.941z" fill="#444"/></svg>
|
After Width: | Height: | Size: 745 B |
Before Width: | Height: | Size: 563 B |
1
packages/node_modules/@node-red/editor-client/src/images/typedInput/expr.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="26" height="36" viewBox="0, 0, 26, 36" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-337.103 -913.25) scale(1.2585)" fill="#444" stroke-width=".795"><circle cx="284.36" cy="733.68" r="1.5" color="#000" style="isolation:auto;mix-blend-mode:normal"/><circle cx="284.33" cy="740.74" r="1.5" color="#000" style="isolation:auto;mix-blend-mode:normal"/><path d="M276.18 727.78l4.396-1.565v18.515c-.711 2.606-2.922 4.394-5.812 5.812l-4.135 1.974-.559-1.192 3.353-1.639c1.459-.724 2.689-1.87 2.869-4.955z" fill-rule="evenodd"/></g></svg>
|
After Width: | Height: | Size: 556 B |
Before Width: | Height: | Size: 588 B |
1
packages/node_modules/@node-red/editor-client/src/images/typedInput/json.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="26" height="36" viewBox="0, 0, 26, 36" xmlns="http://www.w3.org/2000/svg"><path d="M15 5.225v-1.92h2.24q.608 0 1.216.288.608.256 1.12.8.48.512.8 1.312.32.768.32 1.792v5.824q0 .832.224 1.536t.608 1.216q.352.48.832.768.48.256.992.256v2.176q-.512 0-.992.256t-.832.736q-.384.48-.608 1.184t-.224 1.568v5.792q0 1.024-.32 1.792-.32.8-.8 1.312-.512.544-1.12.8-.608.288-1.216.288H15v-1.92h1.6q.48 0 .768-.256.288-.224.48-.64.16-.384.224-.896.064-.48.064-.96v-5.824q0-1.216.352-2.016.32-.8.768-1.28.448-.512.928-.736.448-.224.736-.256v-.096q-.288-.064-.736-.32-.48-.256-.928-.768t-.768-1.28q-.352-.8-.352-1.92V7.977q0-.512-.064-.992-.064-.512-.224-.896-.192-.384-.48-.608-.288-.256-.768-.256zm-3.648 0v-1.92h-2.24q-.608 0-1.216.288-.608.256-1.12.8-.48.512-.8 1.312-.32.768-.32 1.792v5.824q0 .832-.224 1.536t-.608 1.216q-.352.48-.832.768-.48.256-.992.256v2.176q.512 0 .992.256t.832.736q.384.48.608 1.184t.224 1.568v5.792q0 1.024.32 1.792.32.8.8 1.312.512.544 1.12.8.608.288 1.216.288h2.24v-1.92h-1.6q-.48 0-.768-.256-.288-.224-.48-.64-.16-.384-.224-.896-.064-.48-.064-.96v-5.824q0-1.216-.352-2.016-.32-.8-.768-1.28-.448-.512-.928-.736-.448-.224-.736-.256v-.096q.288-.064.736-.32.48-.256.928-.768t.768-1.28q.352-.8.352-1.92V7.977q0-.512.064-.992.064-.512.224-.896.192-.384.48-.608.288-.256.768-.256z" fill="#444"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 502 B |
1
packages/node_modules/@node-red/editor-client/src/images/typedInput/re.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="26" height="36" viewBox="0, 0, 26, 36" xmlns="http://www.w3.org/2000/svg"><path d="M2 19h5v5H2zm16.099-3.304v-5.659h-2.654v5.66l-5.309-2.004-.901 2.404L14.543 18l-3.255 4.557 2.254 1.553 3.255-4.808 3.455 4.808 2.054-1.553L19 18l5.46-1.903-1.002-2.404z" color="#000" fill="#444444"/></svg>
|
After Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 944 B |
1
packages/node_modules/@node-red/editor-client/src/images/typedInput/target.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="26" height="36" viewBox="0, 0, 26, 36" xmlns="http://www.w3.org/2000/svg"><path d="M11 5v5.77a7.542 7.542 0 0 0-5.234 5.25L1 16c-1.432 1.397-1.232 2.722 0 4l4.75-.078a7.542 7.542 0 0 0 5.22 5.297L11 31c1.316 1.303 2.649 1.363 4 0l.009-5.775A7.542 7.542 0 0 0 20.228 20H25c1.261-1.294 1.404-2.623 0-4l-4.774-.01a7.542 7.542 0 0 0-5.23-5.22L15 5c-1.3-1.273-2.63-1.393-4 0zm2 7.499c3.05 0 5.5 2.45 5.5 5.5s-2.45 5.5-5.5 5.5-5.5-2.45-5.5-5.5 2.45-5.5 5.5-5.5z" color="#000" fill="#444"/></svg>
|
After Width: | Height: | Size: 502 B |
@@ -14,7 +14,8 @@
|
||||
* limitations under the License.
|
||||
**/
|
||||
RED.history = (function() {
|
||||
var undo_history = [];
|
||||
var undoHistory = [];
|
||||
var redoHistory = [];
|
||||
|
||||
function undoEvent(ev) {
|
||||
var i;
|
||||
@@ -22,52 +23,81 @@ RED.history = (function() {
|
||||
var node;
|
||||
var subflow;
|
||||
var modifiedTabs = {};
|
||||
var inverseEv;
|
||||
if (ev) {
|
||||
if (ev.t == 'multi') {
|
||||
inverseEv = {
|
||||
t: 'multi',
|
||||
events: []
|
||||
};
|
||||
len = ev.events.length;
|
||||
for (i=len-1;i>=0;i--) {
|
||||
undoEvent(ev.events[i]);
|
||||
var r = undoEvent(ev.events[i]);
|
||||
inverseEv.events.push(r);
|
||||
}
|
||||
} else if (ev.t == 'replace') {
|
||||
inverseEv = {
|
||||
t: 'replace',
|
||||
config: RED.nodes.createCompleteNodeSet(),
|
||||
changed: {},
|
||||
rev: RED.nodes.version()
|
||||
};
|
||||
RED.nodes.clear();
|
||||
var imported = RED.nodes.import(ev.config);
|
||||
imported[0].forEach(function(n) {
|
||||
if (ev.changed[n.id]) {
|
||||
n.changed = true;
|
||||
inverseEv.changed[n.id] = true;
|
||||
}
|
||||
})
|
||||
|
||||
RED.nodes.version(ev.rev);
|
||||
} else if (ev.t == 'add') {
|
||||
inverseEv = {
|
||||
t: "delete",
|
||||
};
|
||||
if (ev.nodes) {
|
||||
inverseEv.nodes = [];
|
||||
for (i=0;i<ev.nodes.length;i++) {
|
||||
node = RED.nodes.node(ev.nodes[i]);
|
||||
if (node.z) {
|
||||
modifiedTabs[node.z] = true;
|
||||
}
|
||||
inverseEv.nodes.push(node);
|
||||
RED.nodes.remove(ev.nodes[i]);
|
||||
}
|
||||
}
|
||||
if (ev.links) {
|
||||
inverseEv.links = [];
|
||||
for (i=0;i<ev.links.length;i++) {
|
||||
inverseEv.links.push(ev.links[i]);
|
||||
RED.nodes.removeLink(ev.links[i]);
|
||||
}
|
||||
}
|
||||
if (ev.workspaces) {
|
||||
inverseEv.workspaces = [];
|
||||
for (i=0;i<ev.workspaces.length;i++) {
|
||||
var workspaceOrder = RED.nodes.getWorkspaceOrder();
|
||||
ev.workspaces[i]._index = workspaceOrder.indexOf(ev.workspaces[i].id);
|
||||
inverseEv.workspaces.push(ev.workspaces[i]);
|
||||
RED.nodes.removeWorkspace(ev.workspaces[i].id);
|
||||
RED.workspaces.remove(ev.workspaces[i]);
|
||||
}
|
||||
}
|
||||
if (ev.subflows) {
|
||||
inverseEv.subflows = [];
|
||||
for (i=0;i<ev.subflows.length;i++) {
|
||||
inverseEv.subflows.push(ev.subflows[i]);
|
||||
RED.nodes.removeSubflow(ev.subflows[i]);
|
||||
RED.workspaces.remove(ev.subflows[i]);
|
||||
}
|
||||
}
|
||||
if (ev.subflow) {
|
||||
inverseEv.subflow = {};
|
||||
if (ev.subflow.instances) {
|
||||
inverseEv.subflow.instances = [];
|
||||
ev.subflow.instances.forEach(function(n) {
|
||||
inverseEv.subflow.instances.push(n);
|
||||
var node = RED.nodes.node(n.id);
|
||||
if (node) {
|
||||
node.changed = n.changed;
|
||||
@@ -83,21 +113,30 @@ RED.history = (function() {
|
||||
}
|
||||
}
|
||||
if (ev.removedLinks) {
|
||||
inverseEv.createdLinks = [];
|
||||
for (i=0;i<ev.removedLinks.length;i++) {
|
||||
inverseEv.createdLinks.push(ev.removedLinks[i]);
|
||||
RED.nodes.addLink(ev.removedLinks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (ev.t == "delete") {
|
||||
inverseEv = {
|
||||
t: "add"
|
||||
};
|
||||
if (ev.workspaces) {
|
||||
inverseEv.workspaces = [];
|
||||
for (i=0;i<ev.workspaces.length;i++) {
|
||||
inverseEv.workspaces.push(ev.workspaces[i]);
|
||||
RED.nodes.addWorkspace(ev.workspaces[i],ev.workspaces[i]._index);
|
||||
RED.workspaces.add(ev.workspaces[i],undefined,ev.workspaces[i]._index);
|
||||
delete ev.workspaces[i]._index;
|
||||
}
|
||||
}
|
||||
if (ev.subflows) {
|
||||
inverseEv.subflows = [];
|
||||
for (i=0;i<ev.subflows.length;i++) {
|
||||
inverseEv.subflows.push(ev.subflows[i]);
|
||||
RED.nodes.addSubflow(ev.subflows[i]);
|
||||
}
|
||||
}
|
||||
@@ -126,8 +165,11 @@ RED.history = (function() {
|
||||
}
|
||||
}
|
||||
if (ev.subflow) {
|
||||
inverseEv.subflow = {};
|
||||
if (ev.subflow.hasOwnProperty('instances')) {
|
||||
inverseEv.subflow.instances = [];
|
||||
ev.subflow.instances.forEach(function(n) {
|
||||
inverseEv.subflow.instances.push(n);
|
||||
var node = RED.nodes.node(n.id);
|
||||
if (node) {
|
||||
node.changed = n.changed;
|
||||
@@ -152,14 +194,25 @@ RED.history = (function() {
|
||||
});
|
||||
}
|
||||
if (ev.nodes) {
|
||||
inverseEv.nodes = [];
|
||||
for (i=0;i<ev.nodes.length;i++) {
|
||||
RED.nodes.add(ev.nodes[i]);
|
||||
modifiedTabs[ev.nodes[i].z] = true;
|
||||
inverseEv.nodes.push(ev.nodes[i].id);
|
||||
}
|
||||
}
|
||||
if (ev.links) {
|
||||
inverseEv.links = [];
|
||||
for (i=0;i<ev.links.length;i++) {
|
||||
RED.nodes.addLink(ev.links[i]);
|
||||
inverseEv.links.push(ev.links[i]);
|
||||
}
|
||||
}
|
||||
if (ev.createdLinks) {
|
||||
inverseEv.removedLinks = [];
|
||||
for (i=0;i<ev.createdLinks.length;i++) {
|
||||
inverseEv.removedLinks.push(ev.createdLinks[i]);
|
||||
RED.nodes.removeLink(ev.createdLinks[i]);
|
||||
}
|
||||
}
|
||||
if (ev.changes) {
|
||||
@@ -179,8 +232,14 @@ RED.history = (function() {
|
||||
|
||||
}
|
||||
} else if (ev.t == "move") {
|
||||
inverseEv = {
|
||||
t: 'move',
|
||||
nodes: []
|
||||
};
|
||||
for (i=0;i<ev.nodes.length;i++) {
|
||||
var n = ev.nodes[i];
|
||||
var rn = {n: n.n, ox: n.n.x, oy: n.n.y, dirty: true, moved: n.moved};
|
||||
inverseEv.nodes.push(rn);
|
||||
n.n.x = n.ox;
|
||||
n.n.y = n.oy;
|
||||
n.n.dirty = true;
|
||||
@@ -188,18 +247,28 @@ RED.history = (function() {
|
||||
}
|
||||
// A move could have caused a link splice
|
||||
if (ev.links) {
|
||||
inverseEv.removedLinks = [];
|
||||
for (i=0;i<ev.links.length;i++) {
|
||||
inverseEv.removedLinks.push(ev.links[i]);
|
||||
RED.nodes.removeLink(ev.links[i]);
|
||||
}
|
||||
}
|
||||
if (ev.removedLinks) {
|
||||
inverseEv.links = [];
|
||||
for (i=0;i<ev.removedLinks.length;i++) {
|
||||
inverseEv.links.push(ev.removedLinks[i]);
|
||||
RED.nodes.addLink(ev.removedLinks[i]);
|
||||
}
|
||||
}
|
||||
} else if (ev.t == "edit") {
|
||||
inverseEv = {
|
||||
t: "edit",
|
||||
changes: {}
|
||||
};
|
||||
inverseEv.node = ev.node;
|
||||
for (i in ev.changes) {
|
||||
if (ev.changes.hasOwnProperty(i)) {
|
||||
inverseEv.changes[i] = ev.node[i];
|
||||
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]);
|
||||
@@ -214,23 +283,34 @@ RED.history = (function() {
|
||||
ev.node[i] = ev.changes[i];
|
||||
}
|
||||
}
|
||||
if (ev.node.type === 'tab' && ev.changes.hasOwnProperty('disabled')) {
|
||||
$("#red-ui-tab-"+(ev.node.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!ev.node.disabled);
|
||||
$("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!ev.node.disabled);
|
||||
}
|
||||
if (ev.subflow) {
|
||||
inverseEv.subflow = {};
|
||||
if (ev.subflow.hasOwnProperty('inputCount')) {
|
||||
inverseEv.subflow.inputCount = ev.node.in.length;
|
||||
if (ev.node.in.length > ev.subflow.inputCount) {
|
||||
inverseEv.subflow.inputs = ev.node.in.slice(ev.subflow.inputCount);
|
||||
ev.node.in.splice(ev.subflow.inputCount);
|
||||
} else if (ev.subflow.inputs.length > 0) {
|
||||
ev.node.in = ev.node.in.concat(ev.subflow.inputs);
|
||||
}
|
||||
}
|
||||
if (ev.subflow.hasOwnProperty('outputCount')) {
|
||||
inverseEv.subflow.outputCount = ev.node.out.length;
|
||||
if (ev.node.out.length > ev.subflow.outputCount) {
|
||||
inverseEv.subflow.outputs = ev.node.out.slice(ev.subflow.outputCount);
|
||||
ev.node.out.splice(ev.subflow.outputCount);
|
||||
} else if (ev.subflow.outputs.length > 0) {
|
||||
ev.node.out = ev.node.out.concat(ev.subflow.outputs);
|
||||
}
|
||||
}
|
||||
if (ev.subflow.hasOwnProperty('instances')) {
|
||||
inverseEv.subflow.instances = [];
|
||||
ev.subflow.instances.forEach(function(n) {
|
||||
inverseEv.subflow.instances.push(n);
|
||||
var node = RED.nodes.node(n.id);
|
||||
if (node) {
|
||||
node.changed = n.changed;
|
||||
@@ -254,9 +334,11 @@ RED.history = (function() {
|
||||
var outputMap;
|
||||
if (ev.outputMap) {
|
||||
outputMap = {};
|
||||
inverseEv.outputMap = {};
|
||||
for (var port in ev.outputMap) {
|
||||
if (ev.outputMap.hasOwnProperty(port) && ev.outputMap[port] !== "-1") {
|
||||
outputMap[ev.outputMap[port]] = port;
|
||||
inverseEv.outputMap[ev.outputMap[port]] = port;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,39 +346,107 @@ RED.history = (function() {
|
||||
RED.editor.validateNode(ev.node);
|
||||
}
|
||||
if (ev.links) {
|
||||
inverseEv.createdLinks = [];
|
||||
for (i=0;i<ev.links.length;i++) {
|
||||
RED.nodes.addLink(ev.links[i]);
|
||||
inverseEv.createdLinks.push(ev.links[i]);
|
||||
}
|
||||
}
|
||||
if (ev.createdLinks) {
|
||||
inverseEv.links = [];
|
||||
for (i=0;i<ev.createdLinks.length;i++) {
|
||||
RED.nodes.removeLink(ev.createdLinks[i]);
|
||||
inverseEv.links.push(ev.createdLinks[i]);
|
||||
}
|
||||
}
|
||||
ev.node.dirty = true;
|
||||
ev.node.changed = ev.changed;
|
||||
} else if (ev.t == "createSubflow") {
|
||||
inverseEv = {
|
||||
t: "deleteSubflow",
|
||||
activeWorkspace: ev.activeWorkspace,
|
||||
dirty: RED.nodes.dirty()
|
||||
};
|
||||
if (ev.nodes) {
|
||||
inverseEv.movedNodes = [];
|
||||
var z = ev.activeWorkspace;
|
||||
RED.nodes.filterNodes({z:ev.subflow.subflow.id}).forEach(function(n) {
|
||||
n.x += ev.subflow.offsetX;
|
||||
n.y += ev.subflow.offsetY;
|
||||
n.z = ev.activeWorkspace;
|
||||
n.dirty = true;
|
||||
inverseEv.movedNodes.push(n.id);
|
||||
RED.nodes.moveNodeToTab(n, z);
|
||||
});
|
||||
inverseEv.subflows = [];
|
||||
for (i=0;i<ev.nodes.length;i++) {
|
||||
inverseEv.subflows.push(RED.nodes.node(ev.nodes[i]));
|
||||
RED.nodes.remove(ev.nodes[i]);
|
||||
}
|
||||
}
|
||||
if (ev.links) {
|
||||
inverseEv.links = [];
|
||||
for (i=0;i<ev.links.length;i++) {
|
||||
inverseEv.links.push(ev.links[i]);
|
||||
RED.nodes.removeLink(ev.links[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inverseEv.subflow = ev.subflow;
|
||||
RED.nodes.removeSubflow(ev.subflow.subflow);
|
||||
RED.workspaces.remove(ev.subflow.subflow);
|
||||
|
||||
if (ev.removedLinks) {
|
||||
inverseEv.createdLinks = [];
|
||||
for (i=0;i<ev.removedLinks.length;i++) {
|
||||
inverseEv.createdLinks.push(ev.removedLinks[i]);
|
||||
RED.nodes.addLink(ev.removedLinks[i]);
|
||||
}
|
||||
}
|
||||
} else if (ev.t == "deleteSubflow") {
|
||||
inverseEv = {
|
||||
t: "createSubflow",
|
||||
activeWorkspace: ev.activeWorkspace,
|
||||
dirty: RED.nodes.dirty(),
|
||||
};
|
||||
if (ev.subflow) {
|
||||
RED.nodes.addSubflow(ev.subflow.subflow);
|
||||
inverseEv.subflow = ev.subflow;
|
||||
}
|
||||
if (ev.subflows) {
|
||||
inverseEv.nodes = [];
|
||||
for (i=0;i<ev.subflows.length;i++) {
|
||||
RED.nodes.add(ev.subflows[i]);
|
||||
inverseEv.nodes.push(ev.subflows[i].id);
|
||||
}
|
||||
}
|
||||
if (ev.movedNodes) {
|
||||
ev.movedNodes.forEach(function(nid) {
|
||||
nn = RED.nodes.node(nid);
|
||||
nn.x -= ev.subflow.offsetX;
|
||||
nn.y -= ev.subflow.offsetY;
|
||||
nn.dirty = true;
|
||||
RED.nodes.moveNodeToTab(nn, ev.subflow.subflow.id);
|
||||
});
|
||||
}
|
||||
if (ev.links) {
|
||||
inverseEv.links = [];
|
||||
for (i=0;i<ev.links.length;i++) {
|
||||
inverseEv.links.push(ev.links[i]);
|
||||
RED.nodes.addLink(ev.links[i]);
|
||||
}
|
||||
}
|
||||
if (ev.createdLinks) {
|
||||
inverseEv.removedLinks = [];
|
||||
for (i=0;i<ev.createdLinks.length;i++) {
|
||||
inverseEv.removedLinks.push(ev.createdLinks[i]);
|
||||
RED.nodes.removeLink(ev.createdLinks[i]);
|
||||
}
|
||||
}
|
||||
} else if (ev.t == "reorder") {
|
||||
inverseEv = {
|
||||
t: 'reorder',
|
||||
order: RED.nodes.getWorkspaceOrder()
|
||||
};
|
||||
if (ev.order) {
|
||||
RED.workspaces.order(ev.order);
|
||||
}
|
||||
@@ -316,6 +466,8 @@ RED.history = (function() {
|
||||
RED.workspaces.refresh();
|
||||
RED.sidebar.config.refresh();
|
||||
RED.subflow.refresh();
|
||||
|
||||
return inverseEv;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -323,28 +475,42 @@ RED.history = (function() {
|
||||
return {
|
||||
//TODO: this function is a placeholder until there is a 'save' event that can be listened to
|
||||
markAllDirty: function() {
|
||||
for (var i=0;i<undo_history.length;i++) {
|
||||
undo_history[i].dirty = true;
|
||||
for (var i=0;i<undoHistory.length;i++) {
|
||||
undoHistory[i].dirty = true;
|
||||
}
|
||||
},
|
||||
list: function() {
|
||||
return undo_history
|
||||
return undoHistory;
|
||||
},
|
||||
depth: function() {
|
||||
return undo_history.length;
|
||||
return undoHistory.length;
|
||||
},
|
||||
push: function(ev) {
|
||||
undo_history.push(ev);
|
||||
undoHistory.push(ev);
|
||||
redoHistory = [];
|
||||
},
|
||||
pop: function() {
|
||||
var ev = undo_history.pop();
|
||||
undoEvent(ev);
|
||||
var ev = undoHistory.pop();
|
||||
var rev = undoEvent(ev);
|
||||
if (rev) {
|
||||
redoHistory.push(rev);
|
||||
}
|
||||
},
|
||||
peek: function() {
|
||||
return undo_history[undo_history.length-1];
|
||||
return undoHistory[undoHistory.length-1];
|
||||
},
|
||||
clear: function() {
|
||||
undo_history = [];
|
||||
undoHistory = [];
|
||||
redoHistory = [];
|
||||
},
|
||||
redo: function() {
|
||||
var ev = redoHistory.pop();
|
||||
if (ev) {
|
||||
var uev = undoEvent(ev);
|
||||
if (uev) {
|
||||
undoHistory.push(uev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -50,8 +50,21 @@ RED.i18n = (function() {
|
||||
}
|
||||
|
||||
},
|
||||
lang: function() {
|
||||
// Gets the active message catalog language. This is based on what
|
||||
// locale the editor is using and what languages are available.
|
||||
//
|
||||
var preferredLangs = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
|
||||
var knownLangs = RED.settings.theme("languages")||["en-US"];
|
||||
for (var i=0;i<preferredLangs.length;i++) {
|
||||
if (knownLangs.indexOf(preferredLangs[i]) > -1) {
|
||||
return preferredLangs[i]
|
||||
}
|
||||
}
|
||||
return 'end-US'
|
||||
},
|
||||
loadNodeCatalog: function(namespace,done) {
|
||||
var languageList = i18n.functions.toLanguages(i18n.detectLanguage());
|
||||
var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
|
||||
var toLoad = languageList.length;
|
||||
languageList.forEach(function(lang) {
|
||||
$.ajax({
|
||||
@@ -73,7 +86,7 @@ RED.i18n = (function() {
|
||||
},
|
||||
|
||||
loadNodeCatalogs: function(done) {
|
||||
var languageList = i18n.functions.toLanguages(i18n.detectLanguage());
|
||||
var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
|
||||
var toLoad = languageList.length;
|
||||
|
||||
languageList.forEach(function(lang) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"*": {
|
||||
"ctrl-shift-p":"core:manage-palette",
|
||||
"alt-shift-p":"core:manage-palette",
|
||||
"ctrl-f": "core:search",
|
||||
"ctrl-shift-f": "core:list-flows",
|
||||
"ctrl-=": "core:zoom-in",
|
||||
@@ -8,6 +8,7 @@
|
||||
"ctrl-0": "core:zoom-reset",
|
||||
"ctrl-enter": "core:confirm-edit-tray",
|
||||
"ctrl-escape": "core:cancel-edit-tray",
|
||||
"ctrl-d": "core:deploy-flows",
|
||||
"ctrl-g i": "core:show-info-tab",
|
||||
"ctrl-g d": "core:show-debug-tab",
|
||||
"ctrl-g c": "core:show-config-tab",
|
||||
@@ -17,17 +18,20 @@
|
||||
"ctrl-space": "core:toggle-sidebar",
|
||||
"ctrl-p": "core:toggle-palette",
|
||||
"ctrl-,": "core:show-user-settings",
|
||||
"ctrl-alt-l": "core:clear-debug-messages",
|
||||
"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",
|
||||
"ctrl-shift-l": "core:show-event-log"
|
||||
"ctrl-shift-l": "core:show-event-log",
|
||||
"ctrl-shift-p":"core:show-action-list"
|
||||
},
|
||||
"red-ui-sidebar-node-config": {
|
||||
"backspace": "core:delete-config-selection",
|
||||
"delete": "core:delete-config-selection",
|
||||
"ctrl-a": "core:select-all-config-nodes",
|
||||
"ctrl-z": "core:undo"
|
||||
"ctrl-z": "core:undo",
|
||||
"ctrl-y": "core:redo"
|
||||
},
|
||||
"red-ui-workspace": {
|
||||
"backspace": "core:delete-selection",
|
||||
@@ -37,6 +41,7 @@
|
||||
"ctrl-x": "core:cut-selection-to-internal-clipboard",
|
||||
"ctrl-v": "core:paste-from-internal-clipboard",
|
||||
"ctrl-z": "core:undo",
|
||||
"ctrl-y": "core:redo",
|
||||
"ctrl-a": "core:select-all-nodes",
|
||||
"shift-?": "core:show-help",
|
||||
"up": "core:move-selection-up",
|
||||
|
@@ -17,6 +17,8 @@ RED.nodes = (function() {
|
||||
|
||||
var node_defs = {};
|
||||
var nodes = [];
|
||||
var nodeTabMap = {};
|
||||
|
||||
var configNodes = {};
|
||||
var links = [];
|
||||
var defaultWorkspace;
|
||||
@@ -213,6 +215,11 @@ RED.nodes = (function() {
|
||||
n.i = nextId+1;
|
||||
}
|
||||
nodes.push(n);
|
||||
if (nodeTabMap[n.z]) {
|
||||
nodeTabMap[n.z][n.id] = n;
|
||||
} else {
|
||||
console.warn("Node added to unknown tab/subflow:",n);
|
||||
}
|
||||
}
|
||||
RED.events.emit('nodes:add',n);
|
||||
}
|
||||
@@ -246,6 +253,9 @@ RED.nodes = (function() {
|
||||
node = getNode(id);
|
||||
if (node) {
|
||||
nodes.splice(nodes.indexOf(node),1);
|
||||
if (nodeTabMap[node.z]) {
|
||||
delete nodeTabMap[node.z][node.id];
|
||||
}
|
||||
removedLinks = links.filter(function(l) { return (l.source === node) || (l.target === node); });
|
||||
removedLinks.forEach(function(l) {links.splice(links.indexOf(l), 1); });
|
||||
var updatedConfigNode = false;
|
||||
@@ -291,6 +301,17 @@ RED.nodes = (function() {
|
||||
return {links:removedLinks,nodes:removedNodes};
|
||||
}
|
||||
|
||||
function moveNodeToTab(node, z) {
|
||||
if (nodeTabMap[node.z]) {
|
||||
delete nodeTabMap[node.z][node.id];
|
||||
}
|
||||
if (!nodeTabMap[z]) {
|
||||
nodeTabMap[z] = {};
|
||||
}
|
||||
nodeTabMap[z][node.id] = node;
|
||||
node.z = z;
|
||||
}
|
||||
|
||||
function removeLink(l) {
|
||||
var index = links.indexOf(l);
|
||||
if (index != -1) {
|
||||
@@ -300,6 +321,8 @@ RED.nodes = (function() {
|
||||
|
||||
function addWorkspace(ws,targetIndex) {
|
||||
workspaces[ws.id] = ws;
|
||||
nodeTabMap[ws.id] = {};
|
||||
|
||||
ws._def = RED.nodes.getType('tab');
|
||||
if (targetIndex === undefined) {
|
||||
workspacesOrder.push(ws.id);
|
||||
@@ -312,6 +335,7 @@ RED.nodes = (function() {
|
||||
}
|
||||
function removeWorkspace(id) {
|
||||
delete workspaces[id];
|
||||
delete nodeTabMap[id];
|
||||
workspacesOrder.splice(workspacesOrder.indexOf(id),1);
|
||||
|
||||
var removedNodes = [];
|
||||
@@ -357,30 +381,32 @@ RED.nodes = (function() {
|
||||
sf.name = subflowName;
|
||||
}
|
||||
subflows[sf.id] = sf;
|
||||
nodeTabMap[sf.id] = {};
|
||||
|
||||
RED.nodes.registerType("subflow:"+sf.id, {
|
||||
defaults:{
|
||||
name:{value:""},
|
||||
env:{value:[]}
|
||||
},
|
||||
icon: function() { return sf.icon||"subflow.png" },
|
||||
icon: function() { return sf.icon||"subflow.svg" },
|
||||
category: sf.category || "subflows",
|
||||
inputs: sf.in.length,
|
||||
outputs: sf.out.length,
|
||||
color: "#da9",
|
||||
color: sf.color || "#DDAA99",
|
||||
label: function() { return this.name||RED.nodes.subflow(sf.id).name },
|
||||
labelStyle: function() { return this.name?"red-ui-flow-node-label-italic":""; },
|
||||
paletteLabel: function() { return RED.nodes.subflow(sf.id).name },
|
||||
inputLabels: function(i) { return sf.inputLabels?sf.inputLabels[i]:null },
|
||||
outputLabels: function(i) { return sf.outputLabels?sf.outputLabels[i]:null },
|
||||
oneditresize: function(size) {
|
||||
var rows = $("#dialog-form>div:not(.node-input-env-container-row)");
|
||||
// var rows = $(".dialog-form>div:not(.node-input-env-container-row)");
|
||||
var height = size.height;
|
||||
for (var i=0; i<rows.size(); i++) {
|
||||
height -= $(rows[i]).outerHeight(true);
|
||||
}
|
||||
var editorRow = $("#dialog-form>div.node-input-env-container-row");
|
||||
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
|
||||
$("#node-input-env-container").editableList('height',height-80);
|
||||
// for (var i=0; i<rows.size(); i++) {
|
||||
// height -= $(rows[i]).outerHeight(true);
|
||||
// }
|
||||
// var editorRow = $("#dialog-form>div.node-input-env-container-row");
|
||||
// height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
|
||||
$("ol.red-ui-editor-subflow-env-list").editableList('height',height);
|
||||
},
|
||||
set:{
|
||||
module: "node-red"
|
||||
@@ -393,6 +419,7 @@ RED.nodes = (function() {
|
||||
}
|
||||
function removeSubflow(sf) {
|
||||
delete subflows[sf.id];
|
||||
delete nodeTabMap[sf.id];
|
||||
registry.removeNodeType("subflow:"+sf.id);
|
||||
}
|
||||
|
||||
@@ -463,7 +490,9 @@ RED.nodes = (function() {
|
||||
node.id = n.id;
|
||||
node.type = n.type;
|
||||
node.z = n.z;
|
||||
|
||||
if (n.d === true) {
|
||||
node.d = true;
|
||||
}
|
||||
if (node.type == "unknown") {
|
||||
for (var p in n._orig) {
|
||||
if (n._orig.hasOwnProperty(p)) {
|
||||
@@ -549,6 +578,7 @@ RED.nodes = (function() {
|
||||
node.in = [];
|
||||
node.out = [];
|
||||
node.env = n.env;
|
||||
node.color = n.color;
|
||||
|
||||
n.in.forEach(function(p) {
|
||||
var nIn = {x:p.x,y:p.y,wires:[]};
|
||||
@@ -581,7 +611,7 @@ RED.nodes = (function() {
|
||||
node.outputLabels = n.outputLabels.slice();
|
||||
}
|
||||
if (n.icon) {
|
||||
if (n.icon !== "node-red/subflow.png") {
|
||||
if (n.icon !== "node-red/subflow.svg") {
|
||||
node.icon = n.icon;
|
||||
}
|
||||
}
|
||||
@@ -815,7 +845,7 @@ RED.nodes = (function() {
|
||||
var m = /^subflow:(.+)$/.exec(newNodes[i].type);
|
||||
if (m) {
|
||||
var subflowId = m[1];
|
||||
var parent = getSubflow(newNodes[i].z || activeWorkspace);
|
||||
var parent = getSubflow(activeWorkspace);
|
||||
if (parent) {
|
||||
var err;
|
||||
if (subflowId === parent.id) {
|
||||
@@ -967,6 +997,9 @@ RED.nodes = (function() {
|
||||
users:[],
|
||||
_config:{}
|
||||
};
|
||||
if (n.hasOwnProperty('d')) {
|
||||
configNode.d = n.d;
|
||||
}
|
||||
for (d in def.defaults) {
|
||||
if (def.defaults.hasOwnProperty(d)) {
|
||||
configNode[d] = n[d];
|
||||
@@ -1016,6 +1049,9 @@ RED.nodes = (function() {
|
||||
if (n.hasOwnProperty('l')) {
|
||||
node.l = n.l;
|
||||
}
|
||||
if (n.hasOwnProperty('d')) {
|
||||
node.d = n.d;
|
||||
}
|
||||
if (createNewIds) {
|
||||
if (subflow_blacklist[n.z]) {
|
||||
continue;
|
||||
@@ -1158,6 +1194,7 @@ RED.nodes = (function() {
|
||||
var nodeTypeArrayReferences = {
|
||||
"catch":"scope",
|
||||
"status":"scope",
|
||||
"complete": "scope",
|
||||
"link in":"links",
|
||||
"link out":"links"
|
||||
}
|
||||
@@ -1258,13 +1295,22 @@ RED.nodes = (function() {
|
||||
// TODO: supports filter.z|type
|
||||
function filterNodes(filter) {
|
||||
var result = [];
|
||||
var searchSet = nodes;
|
||||
var doZFilter = false;
|
||||
if (filter.hasOwnProperty("z")) {
|
||||
if (Object.hasOwnProperty("values") && nodeTabMap.hasOwnProperty(filter.z) ) {
|
||||
searchSet = Object.values(nodeTabMap[filter.z]);
|
||||
} else {
|
||||
doZFilter = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (var n=0;n<nodes.length;n++) {
|
||||
var node = nodes[n];
|
||||
if (filter.hasOwnProperty("z") && node.z !== filter.z) {
|
||||
for (var n=0;n<searchSet.length;n++) {
|
||||
var node = searchSet[n];
|
||||
if (filter.hasOwnProperty("type") && node.type !== filter.type) {
|
||||
continue;
|
||||
}
|
||||
if (filter.hasOwnProperty("type") && node.type !== filter.type) {
|
||||
if (doZFilter && node.z !== filter.z) {
|
||||
continue;
|
||||
}
|
||||
result.push(node);
|
||||
@@ -1331,6 +1377,7 @@ RED.nodes = (function() {
|
||||
function clear() {
|
||||
nodes = [];
|
||||
links = [];
|
||||
nodeTabMap = {};
|
||||
configNodes = {};
|
||||
workspacesOrder = [];
|
||||
var subflowIds = Object.keys(subflows);
|
||||
@@ -1440,6 +1487,8 @@ RED.nodes = (function() {
|
||||
remove: removeNode,
|
||||
clear: clear,
|
||||
|
||||
moveNodeToTab: moveNodeToTab,
|
||||
|
||||
addLink: addLink,
|
||||
removeLink: removeLink,
|
||||
|
||||
|
@@ -107,9 +107,12 @@ var RED = (function() {
|
||||
}
|
||||
|
||||
function loadNodes() {
|
||||
var lang = localStorage.getItem("editor-language")||i18n.detectLanguage();
|
||||
|
||||
$.ajax({
|
||||
headers: {
|
||||
"Accept":"text/html"
|
||||
"Accept":"text/html",
|
||||
"Accept-Language": lang
|
||||
},
|
||||
cache: false,
|
||||
url: 'nodes',
|
||||
@@ -415,8 +418,6 @@ var RED = (function() {
|
||||
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();
|
||||
});
|
||||
RED.comms.subscribe("event-log/#", function(topic,payload) {
|
||||
var id = topic.substring(9);
|
||||
@@ -448,11 +449,16 @@ var RED = (function() {
|
||||
{id:"menu-item-palette",label:RED._("menu.label.palette.show"),toggle:true,onselect:"core:toggle-palette", selected: true},
|
||||
{id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true},
|
||||
{id:"menu-item-event-log",label:RED._("eventLog.title"),onselect:"core:show-event-log"},
|
||||
{id:"menu-item-action-list",label:RED._("keyboard.actionList"),onselect:"core:show-action-list"},
|
||||
null
|
||||
]});
|
||||
menuOptions.push(null);
|
||||
menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),onselect:"core:show-import-dialog"});
|
||||
menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),onselect:"core:show-export-dialog"});
|
||||
if (RED.settings.theme("menu.menu-item-import-library", true)) {
|
||||
menuOptions.push({id: "menu-item-import", label: RED._("menu.label.import"), onselect: "core:show-import-dialog"});
|
||||
}
|
||||
if (RED.settings.theme("menu.menu-item-export-library", true)) {
|
||||
menuOptions.push({id: "menu-item-export", label: RED._("menu.label.export"), onselect: "core:show-export-dialog"});
|
||||
}
|
||||
menuOptions.push(null);
|
||||
menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:"core:search"});
|
||||
menuOptions.push(null);
|
||||
@@ -475,7 +481,9 @@ var RED = (function() {
|
||||
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"});
|
||||
if (RED.settings.theme("menu.menu-item-keyboard-shortcuts", true)) {
|
||||
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",RED._("menu.label.help")),
|
||||
href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")
|
||||
@@ -518,6 +526,7 @@ var RED = (function() {
|
||||
RED.subflow.init();
|
||||
RED.clipboard.init();
|
||||
RED.search.init();
|
||||
RED.actionList.init();
|
||||
RED.editor.init();
|
||||
RED.diff.init();
|
||||
|
||||
|
@@ -56,8 +56,9 @@ RED.settings = (function () {
|
||||
if (key === "auth-tokens") {
|
||||
return JSON.parse(localStorage.getItem(key));
|
||||
} else {
|
||||
var v;
|
||||
try {
|
||||
var v = RED.utils.getMessageProperty(userSettings,key);
|
||||
v = RED.utils.getMessageProperty(userSettings,key);
|
||||
if (v === undefined) {
|
||||
v = defaultIfUndefined;
|
||||
}
|
||||
|
230
packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* 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.actionList = (function() {
|
||||
|
||||
var disabled = false;
|
||||
var dialog = null;
|
||||
var searchInput;
|
||||
var searchResults;
|
||||
var selected = -1;
|
||||
var visible = false;
|
||||
|
||||
var filterTerm = "";
|
||||
var filterTerms = [];
|
||||
var previousActiveElement;
|
||||
|
||||
function ensureSelectedIsVisible() {
|
||||
var selectedEntry = searchResults.find("li.selected");
|
||||
if (selectedEntry.length === 1) {
|
||||
var scrollWindow = searchResults.parent();
|
||||
var scrollHeight = scrollWindow.height();
|
||||
var scrollOffset = scrollWindow.scrollTop();
|
||||
var y = selectedEntry.position().top;
|
||||
var h = selectedEntry.height();
|
||||
if (y+h > scrollHeight) {
|
||||
scrollWindow.animate({scrollTop: '-='+(scrollHeight-(y+h)-10)},50);
|
||||
} else if (y<0) {
|
||||
scrollWindow.animate({scrollTop: '+='+(y-10)},50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createDialog() {
|
||||
dialog = $("<div>",{id:"red-ui-actionList",class:"red-ui-search"}).appendTo("#red-ui-main-container");
|
||||
var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog);
|
||||
searchInput = $('<input type="text" data-i18n="[placeholder]keyboard.filterActions">').appendTo(searchDiv).searchBox({
|
||||
change: function() {
|
||||
filterTerm = $(this).val().trim();
|
||||
filterTerms = filterTerm.split(" ");
|
||||
searchResults.editableList('filter');
|
||||
searchResults.find("li.selected").removeClass("selected");
|
||||
var children = searchResults.children(":visible");
|
||||
if (children.length) {
|
||||
$(children[0]).addClass('selected');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
searchInput.on('keydown',function(evt) {
|
||||
var selectedChild;
|
||||
if (evt.keyCode === 40) {
|
||||
// Down
|
||||
selectedChild = searchResults.find("li.selected");
|
||||
if (!selectedChild.length) {
|
||||
var children = searchResults.children(":visible");
|
||||
if (children.length) {
|
||||
$(children[0]).addClass('selected');
|
||||
}
|
||||
} else {
|
||||
var nextChild = selectedChild.nextAll(":visible").first();
|
||||
if (nextChild.length) {
|
||||
selectedChild.removeClass('selected');
|
||||
nextChild.addClass('selected');
|
||||
}
|
||||
}
|
||||
ensureSelectedIsVisible();
|
||||
evt.preventDefault();
|
||||
} else if (evt.keyCode === 38) {
|
||||
// Up
|
||||
selectedChild = searchResults.find("li.selected");
|
||||
var nextChild = selectedChild.prevAll(":visible").first();
|
||||
if (nextChild.length) {
|
||||
selectedChild.removeClass('selected');
|
||||
nextChild.addClass('selected');
|
||||
}
|
||||
ensureSelectedIsVisible();
|
||||
evt.preventDefault();
|
||||
} else if (evt.keyCode === 13) {
|
||||
// Enter
|
||||
selectedChild = searchResults.find("li.selected");
|
||||
selectCommand(searchResults.editableList('getItem',selectedChild));
|
||||
}
|
||||
});
|
||||
searchInput.i18n();
|
||||
|
||||
var searchResultsDiv = $("<div>",{class:"red-ui-search-results-container"}).appendTo(dialog);
|
||||
searchResults = $('<ol>',{style:"position: absolute;top: 5px;bottom: 5px;left: 5px;right: 5px;"}).appendTo(searchResultsDiv).editableList({
|
||||
addButton: false,
|
||||
addItem: function(container,i,action) {
|
||||
if (action.id === undefined) {
|
||||
$('<div>',{class:"red-ui-search-empty"}).text(RED._('search.empty')).appendTo(container);
|
||||
} else {
|
||||
var div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container);
|
||||
var contentDiv = $('<div>',{class:"red-ui-search-result-action"}).appendTo(div);
|
||||
|
||||
|
||||
$('<div>').text(action.label).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);
|
||||
if (action.key) {
|
||||
$('<div>',{class:"red-ui-search-result-action-key"}).html(RED.keyboard.formatKey(action.key)).appendTo(contentDiv);
|
||||
}
|
||||
div.on("click", function(evt) {
|
||||
evt.preventDefault();
|
||||
selectCommand(action);
|
||||
});
|
||||
}
|
||||
},
|
||||
scrollOnAdd: false,
|
||||
filter: function(item) {
|
||||
if (filterTerm !== "") {
|
||||
var pos=0;
|
||||
for (var i=0;i<filterTerms.length;i++) {
|
||||
var j = item._label.indexOf(filterTerms[i],pos);
|
||||
if (j > -1) {
|
||||
pos = j;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function selectCommand(command) {
|
||||
hide();
|
||||
if (command) {
|
||||
RED.actions.invoke(command.id);
|
||||
}
|
||||
}
|
||||
|
||||
function show(v) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
if (!visible) {
|
||||
previousActiveElement = document.activeElement;
|
||||
RED.keyboard.add("*","escape",function(){hide()});
|
||||
$("#red-ui-header-shade").show();
|
||||
$("#red-ui-editor-shade").show();
|
||||
$("#red-ui-palette-shade").show();
|
||||
$("#red-ui-sidebar-shade").show();
|
||||
$("#red-ui-sidebar-separator").hide();
|
||||
if (dialog === null) {
|
||||
createDialog();
|
||||
}
|
||||
dialog.slideDown(300);
|
||||
searchInput.searchBox('value',v)
|
||||
searchResults.editableList('empty');
|
||||
results = [];
|
||||
var actions = RED.actions.list();
|
||||
actions.sort(function(A,B) {
|
||||
return A.id.localeCompare(B.id);
|
||||
});
|
||||
actions.forEach(function(action) {
|
||||
action.label = action.id.replace(/:/,": ").replace(/-/g," ").replace(/(^| )./g,function() { return arguments[0].toUpperCase()});
|
||||
action._label = action.label.toLowerCase();
|
||||
searchResults.editableList('addItem',action)
|
||||
})
|
||||
RED.events.emit("actionList:open");
|
||||
visible = true;
|
||||
}
|
||||
searchInput.trigger("focus");
|
||||
var children = searchResults.children(":visible");
|
||||
if (children.length) {
|
||||
$(children[0]).addClass('selected');
|
||||
}
|
||||
}
|
||||
|
||||
function hide() {
|
||||
if (visible) {
|
||||
RED.keyboard.remove("escape");
|
||||
visible = false;
|
||||
$("#red-ui-header-shade").hide();
|
||||
$("#red-ui-editor-shade").hide();
|
||||
$("#red-ui-palette-shade").hide();
|
||||
$("#red-ui-sidebar-shade").hide();
|
||||
$("#red-ui-sidebar-separator").show();
|
||||
if (dialog !== null) {
|
||||
dialog.slideUp(200,function() {
|
||||
searchInput.searchBox('value','');
|
||||
});
|
||||
}
|
||||
RED.events.emit("actionList:close");
|
||||
if (previousActiveElement) {
|
||||
$(previousActiveElement).trigger("focus");
|
||||
previousActiveElement = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
RED.actions.add("core:show-action-list",show);
|
||||
|
||||
RED.events.on("editor:open",function() { disabled = true; });
|
||||
RED.events.on("editor:close",function() { disabled = false; });
|
||||
RED.events.on("search:open",function() { disabled = true; });
|
||||
RED.events.on("search:close",function() { disabled = false; });
|
||||
RED.events.on("type-search:open",function() { disabled = true; });
|
||||
RED.events.on("type-search:close",function() { disabled = false; });
|
||||
|
||||
$("#red-ui-header-shade").on('mousedown',hide);
|
||||
$("#red-ui-editor-shade").on('mousedown',hide);
|
||||
$("#red-ui-palette-shade").on('mousedown',hide);
|
||||
$("#red-ui-sidebar-shade").on('mousedown',hide);
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
show: show,
|
||||
hide: hide
|
||||
};
|
||||
|
||||
})();
|
@@ -59,7 +59,7 @@ RED.clipboard = (function() {
|
||||
element.setAttribute('download', "flows.json");
|
||||
element.style.display = 'none';
|
||||
document.body.appendChild(element);
|
||||
element.trigger("click");
|
||||
element.click();
|
||||
document.body.removeChild(element);
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
@@ -396,14 +396,6 @@ RED.clipboard = (function() {
|
||||
label: RED._("library.types.examples")
|
||||
});
|
||||
|
||||
tabs.activateTab("red-ui-clipboard-dialog-import-tab-"+mode);
|
||||
if (mode === 'clipboard') {
|
||||
setTimeout(function() {
|
||||
$("#red-ui-clipboard-dialog-import-text").trigger("focus");
|
||||
},100)
|
||||
}
|
||||
|
||||
|
||||
$("#red-ui-clipboard-dialog-tab-library-name").on("keyup", validateExportFilename);
|
||||
$("#red-ui-clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)});
|
||||
$("#red-ui-clipboard-dialog-export").button("enable");
|
||||
@@ -475,6 +467,14 @@ RED.clipboard = (function() {
|
||||
$("#red-ui-clipboard-dialog-import-file-upload").trigger("click");
|
||||
})
|
||||
|
||||
tabs.activateTab("red-ui-clipboard-dialog-import-tab-"+mode);
|
||||
if (mode === 'clipboard') {
|
||||
setTimeout(function() {
|
||||
$("#red-ui-clipboard-dialog-import-text").trigger("focus");
|
||||
},100)
|
||||
}
|
||||
|
||||
|
||||
dialog.dialog("option","title",RED._("clipboard.importNodes")).dialog("open");
|
||||
popover = RED.popover.create({
|
||||
target: $("#red-ui-clipboard-dialog-import-text"),
|
||||
@@ -521,8 +521,6 @@ RED.clipboard = (function() {
|
||||
label: RED._("library.library")
|
||||
});
|
||||
|
||||
tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+mode);
|
||||
|
||||
$("#red-ui-clipboard-dialog-tab-library-name").on("keyup", validateExportFilename);
|
||||
$("#red-ui-clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)});
|
||||
$("#red-ui-clipboard-dialog-export").button("enable");
|
||||
@@ -638,6 +636,7 @@ RED.clipboard = (function() {
|
||||
} else {
|
||||
$("#red-ui-clipboard-dialog-export-fmt-mini").trigger("click");
|
||||
}
|
||||
tabs.activateTab("red-ui-clipboard-dialog-export-tab-"+mode);
|
||||
dialog.dialog("option","title",RED._("clipboard.exportNodes")).dialog( "open" );
|
||||
|
||||
$("#red-ui-clipboard-dialog-export-text").trigger("focus");
|
||||
@@ -655,7 +654,7 @@ RED.clipboard = (function() {
|
||||
// icon: 'fa fa-hdd-o',
|
||||
// label: RED._("library.types.examples"),
|
||||
// path: "",
|
||||
// children: function(item,done) {
|
||||
// children: function(done,item) {
|
||||
// RED.library.loadLibraryFolder("_examples_","flows","",function(children) {
|
||||
// item.children = children;
|
||||
// done(children);
|
||||
@@ -670,13 +669,14 @@ RED.clipboard = (function() {
|
||||
label: label,
|
||||
path: "",
|
||||
expanded: true,
|
||||
children: function(item,done) {
|
||||
children: function(done, item) {
|
||||
RED.library.loadLibraryFolder(library,"flows","",function(children) {
|
||||
item.children = children;
|
||||
done(children);
|
||||
})
|
||||
}
|
||||
}]);
|
||||
}], true);
|
||||
|
||||
}
|
||||
|
||||
function hideDropTarget() {
|
||||
@@ -730,17 +730,20 @@ RED.clipboard = (function() {
|
||||
init: function() {
|
||||
setupDialogs();
|
||||
|
||||
$('<input type="text" id="red-ui-clipboard-hidden">').appendTo("#red-ui-editor");
|
||||
$('<input type="text" id="red-ui-clipboard-hidden" tabIndex="-1">').appendTo("#red-ui-editor");
|
||||
|
||||
RED.actions.add("core:show-export-dialog",exportNodes);
|
||||
RED.actions.add("core:show-import-dialog",importNodes);
|
||||
|
||||
RED.actions.add("core:library-export",function() { exportNodes('library') });
|
||||
RED.actions.add("core:show-library-export-dialog",function() { exportNodes('library') });
|
||||
RED.actions.add("core:show-library-import-dialog",function() { importNodes('library') });
|
||||
|
||||
RED.events.on("editor:open",function() { disabled = true; });
|
||||
RED.events.on("editor:close",function() { disabled = false; });
|
||||
RED.events.on("search:open",function() { disabled = true; });
|
||||
RED.events.on("search:close",function() { disabled = false; });
|
||||
RED.events.on("actionList:open",function() { disabled = true; });
|
||||
RED.events.on("actionList:close",function() { disabled = false; });
|
||||
RED.events.on("type-search:open",function() { disabled = true; });
|
||||
RED.events.on("type-search:close",function() { disabled = false; });
|
||||
|
||||
|
@@ -32,7 +32,10 @@
|
||||
* - scrollOnAdd : boolean - whether to scroll to newly added items
|
||||
* methods:
|
||||
* - addItem(itemData)
|
||||
* - insertItemAt : function(data,index) - add an item at the specified index
|
||||
* - removeItem(itemData)
|
||||
* - getItemAt(index)
|
||||
* - indexOf(itemData)
|
||||
* - width(width)
|
||||
* - height(height)
|
||||
* - items()
|
||||
@@ -185,6 +188,11 @@
|
||||
}
|
||||
},
|
||||
_destroy: function() {
|
||||
if (this.topContainer) {
|
||||
var tc = this.topContainer;
|
||||
delete this.topContainer;
|
||||
tc.remove();
|
||||
}
|
||||
},
|
||||
_refreshFilter: function() {
|
||||
var that = this;
|
||||
@@ -230,7 +238,24 @@
|
||||
this.uiHeight = desiredHeight;
|
||||
this._resize();
|
||||
},
|
||||
addItem: function(data) {
|
||||
getItemAt: function(index) {
|
||||
var items = this.items();
|
||||
if (index >= 0 && index < items.length) {
|
||||
return $(items[index]).data('data');
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
},
|
||||
indexOf: function(data) {
|
||||
var items = this.items();
|
||||
for (var i=0;i<items.length;i++) {
|
||||
if ($(items[i]).data('data') === data) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
},
|
||||
insertItemAt: function(data,index) {
|
||||
var that = this;
|
||||
data = data || {};
|
||||
var li = $('<li>');
|
||||
@@ -248,7 +273,13 @@
|
||||
});
|
||||
}
|
||||
if (!added) {
|
||||
li.appendTo(this.element);
|
||||
if (index <= 0) {
|
||||
li.prependTo(this.element);
|
||||
} else if (index > that.element.children().length-1) {
|
||||
li.appendTo(this.element);
|
||||
} else {
|
||||
li.insertBefore(this.element.children().eq(index));
|
||||
}
|
||||
}
|
||||
var row = $('<div/>').addClass("red-ui-editableList-item-content").appendTo(li);
|
||||
row.data('data',data);
|
||||
@@ -293,6 +324,9 @@
|
||||
},0);
|
||||
}
|
||||
},
|
||||
addItem: function(data) {
|
||||
this.insertItemAt(data,this.element.children().length)
|
||||
},
|
||||
addItems: function(items) {
|
||||
for (var i=0; i<items.length;i++) {
|
||||
this.addItem(items[i]);
|
||||
@@ -312,6 +346,7 @@
|
||||
},
|
||||
empty: function() {
|
||||
this.element.empty();
|
||||
this.uiContainer.scrollTop(0);
|
||||
},
|
||||
filter: function(filter) {
|
||||
if (filter !== undefined) {
|
||||
@@ -335,6 +370,14 @@
|
||||
if (items.length > 0) {
|
||||
this.uiContainer.scrollTop(this.uiContainer.scrollTop()+items.position().top)
|
||||
}
|
||||
},
|
||||
getItem: function(li) {
|
||||
var el = li.find(".red-ui-editableList-item-content");
|
||||
if (el.length) {
|
||||
return el.data('data');
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
|
@@ -71,7 +71,7 @@ RED.menu = (function() {
|
||||
|
||||
}
|
||||
if (opt.icon !== undefined) {
|
||||
if (/\.png/.test(opt.icon)) {
|
||||
if (/\.(png|svg)/.test(opt.icon)) {
|
||||
linkContent += '<img src="'+opt.icon+'"/> ';
|
||||
} else {
|
||||
linkContent += '<i class="'+(opt.icon?opt.icon:'" style="display: inline-block;"')+'"></i> ';
|
||||
@@ -98,21 +98,10 @@ RED.menu = (function() {
|
||||
return;
|
||||
}
|
||||
if (opt.toggle) {
|
||||
var selected = isSelected(opt.id);
|
||||
if (typeof opt.toggle === "string") {
|
||||
if (!selected) {
|
||||
for (var m in menuItems) {
|
||||
if (menuItems.hasOwnProperty(m)) {
|
||||
var mi = menuItems[m];
|
||||
if (mi.id != opt.id && opt.toggle == mi.toggle) {
|
||||
setSelected(mi.id,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
setSelected(opt.id,true);
|
||||
}
|
||||
if (opt.toggle === true) {
|
||||
setSelected(opt.id, !isSelected(opt.id));
|
||||
} else {
|
||||
setSelected(opt.id, !selected);
|
||||
setSelected(opt.id, true);
|
||||
}
|
||||
} else {
|
||||
triggerAction(opt.id);
|
||||
@@ -209,8 +198,9 @@ RED.menu = (function() {
|
||||
}
|
||||
|
||||
function setSelected(id,state) {
|
||||
var alreadySet = false;
|
||||
if (isSelected(id) == state) {
|
||||
return;
|
||||
alreadySet = true;
|
||||
}
|
||||
var opt = menuItems[id];
|
||||
if (state) {
|
||||
@@ -218,10 +208,26 @@ RED.menu = (function() {
|
||||
} else {
|
||||
$("#"+id).removeClass("active");
|
||||
}
|
||||
if (opt && opt.onselect) {
|
||||
triggerAction(opt.id,state);
|
||||
if (opt) {
|
||||
if (opt.toggle && typeof opt.toggle === "string") {
|
||||
if (state) {
|
||||
for (var m in menuItems) {
|
||||
if (menuItems.hasOwnProperty(m)) {
|
||||
var mi = menuItems[m];
|
||||
if (mi.id != opt.id && opt.toggle == mi.toggle) {
|
||||
setSelected(mi.id,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!alreadySet && opt.onselect) {
|
||||
triggerAction(opt.id,state);
|
||||
}
|
||||
if (!opt.local && !alreadySet) {
|
||||
RED.settings.set(opt.setting||("menu-"+opt.id), state);
|
||||
}
|
||||
}
|
||||
RED.settings.set(opt.setting||("menu-"+opt.id), state);
|
||||
}
|
||||
|
||||
function toggleSelected(id) {
|
||||
@@ -238,7 +244,7 @@ RED.menu = (function() {
|
||||
|
||||
function addItem(id,opt) {
|
||||
var item = createMenuItem(opt);
|
||||
if (opt.group) {
|
||||
if (opt !== null && opt.group) {
|
||||
var groupItems = $("#"+id+"-submenu").children(".red-ui-menu-group-"+opt.group);
|
||||
if (groupItems.length === 0) {
|
||||
item.appendTo("#"+id+"-submenu");
|
||||
|
@@ -52,6 +52,11 @@ RED.popover = (function() {
|
||||
|
||||
var openPopup = function(instant) {
|
||||
if (active) {
|
||||
var existingPopover = target.data("red-ui-popover");
|
||||
if (options.tooltip && existingPopover) {
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
div = $('<div class="red-ui-popover"></div>');
|
||||
if (size !== "default") {
|
||||
div.addClass("red-ui-popover-size-"+size);
|
||||
@@ -122,7 +127,15 @@ RED.popover = (function() {
|
||||
}
|
||||
}
|
||||
div.addClass('red-ui-popover-'+d).css({top: top, left: left});
|
||||
|
||||
if (existingPopover) {
|
||||
existingPopover.close(true);
|
||||
}
|
||||
target.data("red-ui-popover",res)
|
||||
if (options.tooltip) {
|
||||
div.on("mousedown", function(evt) {
|
||||
closePopup(true);
|
||||
});
|
||||
}
|
||||
if (instant) {
|
||||
div.show();
|
||||
} else {
|
||||
@@ -142,6 +155,7 @@ RED.popover = (function() {
|
||||
});
|
||||
}
|
||||
div = null;
|
||||
target.removeData("red-ui-popover",res)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,6 +250,7 @@ RED.popover = (function() {
|
||||
}
|
||||
}
|
||||
return RED.popover.create({
|
||||
tooltip: true,
|
||||
target:target,
|
||||
trigger: "hover",
|
||||
size: "small",
|
||||
@@ -243,6 +258,71 @@ RED.popover = (function() {
|
||||
content: label,
|
||||
delay: { show: 750, hide: 50 }
|
||||
});
|
||||
},
|
||||
panel: function(content) {
|
||||
var panel = $('<div class="red-ui-editor-dialog red-ui-popover-panel"></div>');
|
||||
panel.css({ display: "none" });
|
||||
panel.appendTo(document.body);
|
||||
content.appendTo(panel);
|
||||
var closeCallback;
|
||||
|
||||
function hide() {
|
||||
$(document).off("mousedown.red-ui-popover-panel-close");
|
||||
panel.hide();
|
||||
panel.css({
|
||||
height: "auto"
|
||||
});
|
||||
panel.remove();
|
||||
}
|
||||
function show(options) {
|
||||
var closeCallback = options.onclose;
|
||||
var target = options.target;
|
||||
var align = options.align || "left";
|
||||
|
||||
var pos = target.offset();
|
||||
var targetWidth = target.width();
|
||||
var targetHeight = target.height();
|
||||
var panelHeight = panel.height();
|
||||
var panelWidth = panel.width();
|
||||
|
||||
var top = (targetHeight+pos.top);
|
||||
if (top+panelHeight > $(window).height()) {
|
||||
top -= (top+panelHeight)-$(window).height() + 5;
|
||||
}
|
||||
if (top < 0) {
|
||||
panelHeight.height(panelHeight+top)
|
||||
top = 0;
|
||||
}
|
||||
if (align === "left") {
|
||||
panel.css({
|
||||
top: top+"px",
|
||||
left: (pos.left)+"px",
|
||||
});
|
||||
} else if(align === "right") {
|
||||
panel.css({
|
||||
top: top+"px",
|
||||
left: (pos.left-panelWidth)+"px",
|
||||
});
|
||||
}
|
||||
panel.slideDown(100);
|
||||
|
||||
$(document).on("mousedown.red-ui-popover-panel-close", function(event) {
|
||||
if(!$(event.target).closest(panel).length && !$(event.target).closest(".red-ui-editor-dialog").length) {
|
||||
if (closeCallback) {
|
||||
closeCallback();
|
||||
}
|
||||
hide();
|
||||
}
|
||||
// if ($(event.target).closest(target).length) {
|
||||
// event.preventDefault();
|
||||
// }
|
||||
})
|
||||
}
|
||||
return {
|
||||
container: panel,
|
||||
show:show,
|
||||
hide:hide
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -87,6 +87,7 @@
|
||||
that._trigger("change");
|
||||
},this.options.delay);
|
||||
} else {
|
||||
this.lastSent = this.element.val();
|
||||
this._trigger("change");
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,9 @@
|
||||
RED.tabs = (function() {
|
||||
|
||||
var defaultTabIcon = "fa fa-lemon-o";
|
||||
var dragActive = false;
|
||||
var dblClickTime;
|
||||
var dblClickArmed = false;
|
||||
|
||||
function createTabs(options) {
|
||||
var tabs = {};
|
||||
@@ -201,12 +204,21 @@ RED.tabs = (function() {
|
||||
}
|
||||
|
||||
function onTabClick(evt) {
|
||||
evt.preventDefault();
|
||||
if (dragActive) {
|
||||
return
|
||||
}
|
||||
if (dblClickTime && Date.now()-dblClickTime < 400) {
|
||||
dblClickTime = 0;
|
||||
dblClickArmed = true;
|
||||
return onTabDblClick.call(this,evt);
|
||||
}
|
||||
dblClickTime = Date.now();
|
||||
|
||||
var currentTab = ul.find("li.red-ui-tab.active");
|
||||
var thisTab = $(this).parent();
|
||||
var fireSelectionChanged = false;
|
||||
if (options.onselect) {
|
||||
if (evt.metaKey) {
|
||||
if (evt.metaKey || evt.ctrlKey) {
|
||||
if (thisTab.hasClass("selected")) {
|
||||
thisTab.removeClass("selected");
|
||||
if (thisTab[0] !== currentTab[0]) {
|
||||
@@ -267,7 +279,6 @@ RED.tabs = (function() {
|
||||
if (fireSelectionChanged) {
|
||||
selectionChanged();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateScroll() {
|
||||
@@ -289,7 +300,6 @@ RED.tabs = (function() {
|
||||
}
|
||||
function onTabDblClick(evt) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
if (evt.metaKey || evt.shiftKey) {
|
||||
return;
|
||||
}
|
||||
@@ -418,7 +428,11 @@ RED.tabs = (function() {
|
||||
|
||||
}
|
||||
|
||||
ul.find("li.red-ui-tab a").on("click",onTabClick).on("dblclick",onTabDblClick);
|
||||
ul.find("li.red-ui-tab a")
|
||||
.on("mouseup",onTabClick)
|
||||
.on("click", function(evt) {evt.preventDefault(); })
|
||||
.on("dblclick", function(evt) {evt.stopPropagation(); evt.preventDefault(); })
|
||||
|
||||
setTimeout(function() {
|
||||
updateTabWidths();
|
||||
},0);
|
||||
@@ -524,8 +538,9 @@ RED.tabs = (function() {
|
||||
RED.popover.tooltip($(pinnedLink), tab.name, tab.action);
|
||||
|
||||
}
|
||||
link.on("click",onTabClick);
|
||||
link.on("dblclick",onTabDblClick);
|
||||
link.on("mouseup",onTabClick);
|
||||
link.on("click", function(evt) { evt.preventDefault(); })
|
||||
link.on("dblclick", function(evt) { evt.stopPropagation(); evt.preventDefault(); })
|
||||
|
||||
|
||||
if (tab.closeable) {
|
||||
@@ -560,6 +575,8 @@ RED.tabs = (function() {
|
||||
axis:"x",
|
||||
distance: 20,
|
||||
start: function(event,ui) {
|
||||
if (dblClickArmed) { dblClickArmed = false; return false }
|
||||
dragActive = true;
|
||||
originalTabOrder = [];
|
||||
tabElements = [];
|
||||
ul.children().each(function(i) {
|
||||
@@ -615,6 +632,7 @@ RED.tabs = (function() {
|
||||
}
|
||||
},
|
||||
stop: function(event,ui) {
|
||||
dragActive = false;
|
||||
ul.children().css({position:"relative",left:"",transition:""});
|
||||
if (!li.hasClass('active')) {
|
||||
li.css({zIndex:""});
|
||||
|
@@ -39,15 +39,14 @@
|
||||
var baseClass = this.options.baseClass || "red-ui-button";
|
||||
var enabledIcon = this.options.enabledIcon || "fa-check-square-o";
|
||||
var disabledIcon = this.options.disabledIcon || "fa-square-o";
|
||||
var enabledLabel = this.options.enabledLabel || RED._("editor:workspace.enabled");
|
||||
var disabledLabel = this.options.disabledLabel || RED._("editor:workspace.disabled");
|
||||
var enabledLabel = this.options.hasOwnProperty('enabledLabel') ? this.options.enabledLabel : RED._("editor:workspace.enabled");
|
||||
var disabledLabel = this.options.hasOwnProperty('disabledLabel') ? this.options.disabledLabel : RED._("editor:workspace.disabled");
|
||||
|
||||
this.element.addClass("red-ui-toggleButton");
|
||||
this.element.css("display","none");
|
||||
this.element.on("focus", function() {
|
||||
that.button.focus();
|
||||
});
|
||||
this.button = $('<button type="button" class="'+baseClass+' toggle single"><i class="fa"></i> <span></span></button>');
|
||||
this.button = $('<button type="button" class="red-ui-toggleButton '+baseClass+' toggle single"><i class="fa"></i> <span></span></button>');
|
||||
if (this.options.class) {
|
||||
this.button.addClass(this.options.class)
|
||||
}
|
||||
|
@@ -20,6 +20,10 @@
|
||||
* - data : array - initial items to display in tree
|
||||
* - multi : boolean - if true, .selected will return an array of results
|
||||
* otherwise, returns the first selected item
|
||||
* - sortable: boolean/string - TODO: see editableList
|
||||
* - rootSortable: boolean - if 'sortable' is set, then setting this to
|
||||
* false, prevents items being sorted to the
|
||||
* top level of the tree
|
||||
*
|
||||
* methods:
|
||||
* - data(items) - clears existing items and replaces with new data
|
||||
@@ -27,25 +31,57 @@
|
||||
* events:
|
||||
* - treelistselect : function(event, item) {}
|
||||
* - treelistconfirm : function(event,item) {}
|
||||
* - treelistchangeparent: function(event,item, oldParent, newParent) {}
|
||||
*
|
||||
* data:
|
||||
* [
|
||||
* {
|
||||
* label: 'Local', // label for the item
|
||||
* sublabel: 'Local', // a sub-label for the item
|
||||
* icon: 'fa fa-rocket', // (optional) icon for the item
|
||||
* selected: true/false, // (optional) if present, display checkbox accordingly
|
||||
* children: [] | function(item,done) // (optional) an array of child items, or a function
|
||||
* children: [] | function(done,item) // (optional) an array of child items, or a function
|
||||
* // that will call the `done` callback with an array
|
||||
* // of child items
|
||||
* expanded: true/false, // show the child items by default
|
||||
* deferBuild: true/false, // don't build any ui elements for the item's children
|
||||
* until it is expanded by the user.
|
||||
* element: // custom dom element to use for the item - ignored if `label` is set
|
||||
* }
|
||||
* ]
|
||||
*
|
||||
*
|
||||
*
|
||||
* var treeList = $("<div>").css({width: "100%", height: "100%"}).treeList({data:[...]})
|
||||
* treeList.on('treelistselect', function(e,item) { console.log(item)})
|
||||
* treeList.treeList('data',[ ... ] )
|
||||
*
|
||||
*
|
||||
* After `data` has been added to the tree, each item is augmented the following
|
||||
* properties and functions:
|
||||
*
|
||||
* item.parent - set to the parent item
|
||||
* item.treeList.container
|
||||
* item.treeList.label - the label element for the item
|
||||
* item.treeList.depth - the depth in the tree (0 == root)
|
||||
* item.treeList.parentList - the editableList instance this item is in
|
||||
* item.treeList.remove() - removes the item from the tree
|
||||
* item.treeList.makeLeaf(detachChildElements) - turns an element with children into a leaf node,
|
||||
* removing the UI decoration etc.
|
||||
* detachChildElements - any children with custom
|
||||
* elements will be detached rather than removed
|
||||
* so jQuery event handlers are preserved in case
|
||||
* the child elements need to be reattached later
|
||||
* item.treeList.makeParent(children) - turns an element into a parent node, adding the necessary
|
||||
* UI decoration.
|
||||
* item.treeList.insertChildAt(newItem,position,select) - adds a child item an the specified position.
|
||||
* Optionally selects the item after adding.
|
||||
* item.treeList.addChild(newItem,select) - appends a child item.
|
||||
* Optionally selects the item after adding.
|
||||
* item.treeList.expand(done) - expands the parent item to show children. Optional 'done' callback.
|
||||
* item.treeList.collapse() - collapse the parent item to hide children.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
$.widget( "nodered.treeList", {
|
||||
@@ -116,20 +152,30 @@
|
||||
});
|
||||
this._data = [];
|
||||
|
||||
this._topList = $('<ol>').css({
|
||||
this._topList = $('<ol class="red-ui-treeList-list">').css({
|
||||
position:'absolute',
|
||||
top: 0,
|
||||
left:0,
|
||||
right:0,
|
||||
bottom:0
|
||||
}).appendTo(wrapper).editableList({
|
||||
}).appendTo(wrapper);
|
||||
|
||||
var topListOptions = {
|
||||
addButton: false,
|
||||
scrollOnAdd: false,
|
||||
height: '100%',
|
||||
addItem: function(container,i,item) {
|
||||
that._addSubtree(that._topList,container,item,0);
|
||||
}
|
||||
})
|
||||
};
|
||||
if (this.options.rootSortable !== false && !!this.options.sortable) {
|
||||
topListOptions.sortable = this.options.sortable;
|
||||
topListOptions.connectWith = '.red-ui-treeList-sortable';
|
||||
this._topList.addClass('red-ui-treeList-sortable');
|
||||
}
|
||||
this._topList.editableList(topListOptions)
|
||||
|
||||
|
||||
if (this.options.data) {
|
||||
this.data(this.options.data);
|
||||
}
|
||||
@@ -171,23 +217,82 @@
|
||||
},
|
||||
_addChildren: function(container,parent,children,depth) {
|
||||
var that = this;
|
||||
var subtree = $('<ol>').appendTo(container).editableList({
|
||||
var subtree = $('<ol class="red-ui-treeList-list">').appendTo(container).editableList({
|
||||
connectWith: ".red-ui-treeList-sortable",
|
||||
sortable: that.options.sortable,
|
||||
addButton: false,
|
||||
scrollOnAdd: false,
|
||||
height: 'auto',
|
||||
addItem: function(container,i,item) {
|
||||
that._addSubtree(subtree,container,item,depth+1);
|
||||
},
|
||||
sortItems: function(data) {
|
||||
var children = [];
|
||||
var reparented = [];
|
||||
data.each(function() {
|
||||
var child = $(this).data('data');
|
||||
children.push(child);
|
||||
var evt = that._fixDepths(parent,child);
|
||||
if (evt) {
|
||||
reparented.push(evt);
|
||||
}
|
||||
})
|
||||
if (Array.isArray(parent.children)) {
|
||||
parent.children = children;
|
||||
}
|
||||
reparented.forEach(function(evt) {
|
||||
that._trigger("changeparent",null,evt);
|
||||
});
|
||||
that._trigger("sort",null,parent);
|
||||
}
|
||||
});
|
||||
if (!!that.options.sortable) {
|
||||
subtree.addClass('red-ui-treeList-sortable');
|
||||
}
|
||||
for (var i=0;i<children.length;i++) {
|
||||
children[i].parent = parent;
|
||||
subtree.editableList('addItem',children[i])
|
||||
}
|
||||
return subtree;
|
||||
},
|
||||
_fixDepths: function(parent,child) {
|
||||
// If child has just been moved into parent in the UI
|
||||
// this will fix up the internal data structures to match.
|
||||
// The calling function must take care of getting child
|
||||
// into the parent.children array. The rest is up to us.
|
||||
var that = this;
|
||||
var reparentedEvent = null;
|
||||
if (child.parent !== parent) {
|
||||
reparented = true;
|
||||
var oldParent = child.parent;
|
||||
child.parent = parent;
|
||||
reparentedEvent = {
|
||||
item: child,
|
||||
old: oldParent,
|
||||
}
|
||||
}
|
||||
if (child.depth !== parent.depth+1) {
|
||||
child.depth = parent.depth+1;
|
||||
var labelPaddingWidth = ((child.gutter?child.gutter.width()+2:0)+(child.depth*20));
|
||||
child.treeList.labelPadding.width(labelPaddingWidth+'px');
|
||||
if (child.element) {
|
||||
$(child.element).css({
|
||||
width: "calc(100% - "+(labelPaddingWidth+20+(child.icon?20:0))+"px)"
|
||||
})
|
||||
}
|
||||
// This corrects all child item depths
|
||||
if (child.children && Array.isArray(child.children)) {
|
||||
child.children.forEach(function(item) {
|
||||
that._fixDepths(child,item);
|
||||
})
|
||||
}
|
||||
}
|
||||
return reparentedEvent;
|
||||
},
|
||||
_addSubtree: function(parentList, container, item, depth) {
|
||||
var that = this;
|
||||
item.treeList = {};
|
||||
item.treeList.depth = depth;
|
||||
item.treeList.container = container;
|
||||
|
||||
item.treeList.parentList = parentList;
|
||||
@@ -196,87 +301,80 @@
|
||||
if (item.parent) {
|
||||
var index = item.parent.children.indexOf(item);
|
||||
item.parent.children.splice(index,1)
|
||||
that._trigger("sort",null,item.parent);
|
||||
}
|
||||
}
|
||||
var labelNodeType = "<div>";
|
||||
// if (item.children && item.hasOwnProperty('selected')) {
|
||||
// labelNodeType = "<div>";
|
||||
// }
|
||||
var label = $(labelNodeType,{class:"red-ui-treeList-label"}).appendTo(container);
|
||||
|
||||
var label = $("<div>",{class:"red-ui-treeList-label"}).appendTo(container);
|
||||
item.treeList.label = label;
|
||||
if (item.class) {
|
||||
label.addClass(item.class);
|
||||
}
|
||||
label.css({
|
||||
paddingLeft: (depth*15)+'px'
|
||||
})
|
||||
if (item.gutter) {
|
||||
item.gutter.css({
|
||||
position: 'absolute'
|
||||
}).appendTo(label)
|
||||
|
||||
}
|
||||
var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20);
|
||||
item.treeList.labelPadding = $('<span>').css({
|
||||
display: "inline-block",
|
||||
width: labelPaddingWidth+'px'
|
||||
}).appendTo(label);
|
||||
|
||||
label.on('mouseover',function(e) { that._trigger('itemmouseover',e,item); })
|
||||
label.on('mouseout',function(e) { that._trigger('itemmouseout',e,item); })
|
||||
label.on('mouseenter',function(e) { that._trigger('itemmouseenter',e,item); })
|
||||
label.on('mouseleave',function(e) { that._trigger('itemmouseleave',e,item); })
|
||||
|
||||
if (item.children) {
|
||||
item.treeList.addChild = function(newItem,select) {
|
||||
item.treeList.childList.editableList('addItem',newItem)
|
||||
newItem.parent = item;
|
||||
item.children.push(newItem);
|
||||
if (select) {
|
||||
setTimeout(function() {
|
||||
that.select(newItem)
|
||||
},100);
|
||||
}
|
||||
item.treeList.makeLeaf = function(detachChildElements) {
|
||||
if (!treeListIcon.children().length) {
|
||||
// Already a leaf
|
||||
return
|
||||
}
|
||||
item.treeList.expand = function(done) {
|
||||
if (container.hasClass("expanded")) {
|
||||
done && done();
|
||||
return;
|
||||
}
|
||||
if (!container.hasClass("built") && typeof item.children === 'function') {
|
||||
container.addClass('built');
|
||||
var childrenAdded = false;
|
||||
var spinner;
|
||||
var startTime = 0;
|
||||
item.children(item,function(children) {
|
||||
childrenAdded = true;
|
||||
item.treeList.childList = that._addChildren(container,item,children,depth).hide();
|
||||
var delta = Date.now() - startTime;
|
||||
if (delta < 400) {
|
||||
setTimeout(function() {
|
||||
item.treeList.childList.slideDown('fast');
|
||||
if (spinner) {
|
||||
spinner.remove();
|
||||
}
|
||||
},400-delta);
|
||||
} else {
|
||||
item.treeList.childList.slideDown('fast');
|
||||
if (spinner) {
|
||||
spinner.remove();
|
||||
if (detachChildElements && item.children) {
|
||||
var detachChildren = function(item) {
|
||||
if (item.children) {
|
||||
item.children.forEach(function(child) {
|
||||
if (child.element) {
|
||||
child.element.detach();
|
||||
}
|
||||
}
|
||||
done && done();
|
||||
that._trigger("childrenloaded",null,item)
|
||||
});
|
||||
if (!childrenAdded) {
|
||||
startTime = Date.now();
|
||||
spinner = $('<div class="red-ui-treeList-spinner">').css({
|
||||
"background-position": (35+depth*15)+'px 50%'
|
||||
}).appendTo(container);
|
||||
if (child.gutter) {
|
||||
child.gutter.detach();
|
||||
}
|
||||
detachChildren(child);
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
item.treeList.childList.slideDown('fast');
|
||||
done && done();
|
||||
}
|
||||
container.addClass("expanded");
|
||||
detachChildren(item);
|
||||
}
|
||||
item.treeList.collapse = function() {
|
||||
item.treeList.childList.slideUp('fast');
|
||||
container.removeClass("expanded");
|
||||
treeListIcon.empty();
|
||||
if (!item.deferBuild) {
|
||||
item.treeList.childList.remove();
|
||||
delete item.treeList.childList;
|
||||
}
|
||||
|
||||
$('<span class="red-ui-treeList-icon"><i class="fa fa-angle-right" /></span>').appendTo(label);
|
||||
label.off("click.red-ui-treeList-expand");
|
||||
treeListIcon.off("click.red-ui-treeList-expand");
|
||||
delete item.children;
|
||||
container.removeClass("expanded");
|
||||
}
|
||||
item.treeList.makeParent = function(children) {
|
||||
if (treeListIcon.children().length) {
|
||||
// Already a parent because we've got the angle-right icon
|
||||
return;
|
||||
}
|
||||
$('<i class="fa fa-angle-right" />').appendTo(treeListIcon);
|
||||
treeListIcon.on("click.red-ui-treeList-expand", function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (container.hasClass("expanded")) {
|
||||
item.treeList.collapse();
|
||||
} else {
|
||||
item.treeList.expand();
|
||||
}
|
||||
});
|
||||
// $('<span class="red-ui-treeList-icon"><i class="fa fa-folder-o" /></span>').appendTo(label);
|
||||
label.on("click", function(e) {
|
||||
label.on("click.red-ui-treeList-expand", function(e) {
|
||||
if (container.hasClass("expanded")) {
|
||||
if (item.hasOwnProperty('selected') || label.hasClass("selected")) {
|
||||
item.treeList.collapse();
|
||||
@@ -285,9 +383,97 @@
|
||||
item.treeList.expand();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
$('<span class="red-ui-treeList-icon"></span>').appendTo(label);
|
||||
if (!item.children) {
|
||||
item.children = children||[];
|
||||
item.treeList.childList = that._addChildren(container,item,item.children,depth).hide();
|
||||
}
|
||||
}
|
||||
item.treeList.insertChildAt = function(newItem,position,select) {
|
||||
newItem.parent = item;
|
||||
item.children.splice(position,0,newItem);
|
||||
|
||||
if (!item.deferBuild) {
|
||||
item.treeList.childList.editableList('insertItemAt',newItem,position)
|
||||
if (select) {
|
||||
setTimeout(function() {
|
||||
that.select(newItem)
|
||||
},100);
|
||||
}
|
||||
that._trigger("sort",null,item);
|
||||
}
|
||||
}
|
||||
item.treeList.addChild = function(newItem,select) {
|
||||
item.treeList.insertChildAt(newItem,item.children.length,select);
|
||||
}
|
||||
item.treeList.expand = function(done) {
|
||||
if (!item.children) {
|
||||
return;
|
||||
}
|
||||
if (container.hasClass("expanded")) {
|
||||
if (done) { done() }
|
||||
return;
|
||||
}
|
||||
if (!container.hasClass("built") && (item.deferBuild || typeof item.children === 'function')) {
|
||||
container.addClass('built');
|
||||
var childrenAdded = false;
|
||||
var spinner;
|
||||
var startTime = 0;
|
||||
var completeBuild = function(children) {
|
||||
childrenAdded = true;
|
||||
item.treeList.childList = that._addChildren(container,item,children,depth).hide();
|
||||
var delta = Date.now() - startTime;
|
||||
if (delta < 400) {
|
||||
setTimeout(function() {
|
||||
item.treeList.childList.slideDown('fast');
|
||||
if (spinner) {
|
||||
spinner.remove();
|
||||
}
|
||||
},400-delta);
|
||||
} else {
|
||||
item.treeList.childList.slideDown('fast');
|
||||
if (spinner) {
|
||||
spinner.remove();
|
||||
}
|
||||
}
|
||||
if (done) { done() }
|
||||
that._trigger("childrenloaded",null,item)
|
||||
}
|
||||
if (typeof item.children === 'function') {
|
||||
item.children(completeBuild,item);
|
||||
} else {
|
||||
delete item.deferBuild;
|
||||
completeBuild(item.children);
|
||||
}
|
||||
if (!childrenAdded) {
|
||||
startTime = Date.now();
|
||||
spinner = $('<div class="red-ui-treeList-spinner">').css({
|
||||
"background-position": (35+depth*20)+'px 50%'
|
||||
}).appendTo(container);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (that._loadingData) {
|
||||
item.treeList.childList.show();
|
||||
} else {
|
||||
item.treeList.childList.slideDown('fast');
|
||||
}
|
||||
if (done) { done() }
|
||||
}
|
||||
container.addClass("expanded");
|
||||
}
|
||||
item.treeList.collapse = function() {
|
||||
if (!item.children) {
|
||||
return;
|
||||
}
|
||||
item.treeList.childList.slideUp('fast');
|
||||
container.removeClass("expanded");
|
||||
}
|
||||
|
||||
var treeListIcon = $('<span class="red-ui-treeList-icon"></span>').appendTo(label);
|
||||
if (item.children) {
|
||||
item.treeList.makeParent();
|
||||
}
|
||||
|
||||
if (item.hasOwnProperty('selected')) {
|
||||
var selectWrapper = $('<span class="red-ui-treeList-icon"></span>').appendTo(label);
|
||||
var cb = $('<input class="red-ui-treeList-checkbox" type="checkbox">').prop('checked',item.selected).appendTo(selectWrapper);
|
||||
@@ -326,19 +512,22 @@
|
||||
if (item.icon) {
|
||||
$('<span class="red-ui-treeList-icon"><i class="'+item.icon+'" /></span>').appendTo(label);
|
||||
}
|
||||
if (item.label || item.sublabel) {
|
||||
if (item.label) {
|
||||
if (item.hasOwnProperty('label') || item.hasOwnProperty('sublabel')) {
|
||||
if (item.hasOwnProperty('label')) {
|
||||
$('<span class="red-ui-treeList-label-text"></span>').text(item.label).appendTo(label);
|
||||
}
|
||||
if (item.sublabel) {
|
||||
if (item.hasOwnProperty('sublabel')) {
|
||||
$('<span class="red-ui-treeList-sublabel-text"></span>').text(item.sublabel).appendTo(label);
|
||||
}
|
||||
|
||||
} else if (item.element) {
|
||||
$(item.element).appendTo(label);
|
||||
$(item.element).css({
|
||||
width: "calc(100% - "+(labelPaddingWidth+20+(item.icon?20:0))+"px)"
|
||||
})
|
||||
}
|
||||
if (item.children) {
|
||||
if (Array.isArray(item.children)) {
|
||||
if (Array.isArray(item.children) && !item.deferBuild) {
|
||||
item.treeList.childList = that._addChildren(container,item,item.children,depth).hide();
|
||||
}
|
||||
if (item.expanded) {
|
||||
@@ -350,12 +539,17 @@
|
||||
this._topList.editableList('empty');
|
||||
},
|
||||
data: function(items) {
|
||||
var that = this;
|
||||
if (items !== undefined) {
|
||||
this._data = items;
|
||||
this._topList.editableList('empty');
|
||||
this._loadingData = true;
|
||||
for (var i=0; i<items.length;i++) {
|
||||
this._topList.editableList('addItem',items[i]);
|
||||
}
|
||||
setTimeout(function() {
|
||||
delete that._loadingData;
|
||||
},200);
|
||||
this._trigger("select")
|
||||
|
||||
} else {
|
||||
@@ -384,7 +578,11 @@
|
||||
})
|
||||
return res;
|
||||
}
|
||||
return s.parent().data('data');
|
||||
if (s.length) {
|
||||
return s.parent().data('data');
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -32,6 +32,12 @@
|
||||
return v;
|
||||
}
|
||||
}
|
||||
var mapDeprecatedIcon = function(icon) {
|
||||
if (/^red\/images\/typedInput\/.+\.png$/.test(icon)) {
|
||||
icon = icon.replace(/.png$/,".svg");
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
var allOptions = {
|
||||
msg: {value:"msg",label:"msg.",validate:RED.utils.validatePropertyExpression},
|
||||
flow: {value:"flow",label:"flow.",hasValue:true,
|
||||
@@ -46,13 +52,13 @@
|
||||
parse: contextParse,
|
||||
export: contextExport
|
||||
},
|
||||
str: {value:"str",label:"string",icon:"red/images/typedInput/az.png"},
|
||||
num: {value:"num",label:"number",icon:"red/images/typedInput/09.png",validate:/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/},
|
||||
bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.png",options:["true","false"]},
|
||||
str: {value:"str",label:"string",icon:"red/images/typedInput/az.svg"},
|
||||
num: {value:"num",label:"number",icon:"red/images/typedInput/09.svg",validate:/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/},
|
||||
bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.svg",options:["true","false"]},
|
||||
json: {
|
||||
value:"json",
|
||||
label:"JSON",
|
||||
icon:"red/images/typedInput/json.png",
|
||||
icon:"red/images/typedInput/json.svg",
|
||||
validate: function(v) { try{JSON.parse(v);return true;}catch(e){return false;}},
|
||||
expand: function() {
|
||||
var that = this;
|
||||
@@ -74,12 +80,12 @@
|
||||
})
|
||||
}
|
||||
},
|
||||
re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.png"},
|
||||
date: {value:"date",label:"timestamp",hasValue:false},
|
||||
re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.svg"},
|
||||
date: {value:"date",label:"timestamp",icon:"fa fa-clock-o",hasValue:false},
|
||||
jsonata: {
|
||||
value: "jsonata",
|
||||
label: "expression",
|
||||
icon: "red/images/typedInput/expr.png",
|
||||
icon: "red/images/typedInput/expr.svg",
|
||||
validate: function(v) { try{jsonata(v);return true;}catch(e){return false;}},
|
||||
expand:function() {
|
||||
var that = this;
|
||||
@@ -94,7 +100,7 @@
|
||||
bin: {
|
||||
value: "bin",
|
||||
label: "buffer",
|
||||
icon: "red/images/typedInput/bin.png",
|
||||
icon: "red/images/typedInput/bin.svg",
|
||||
expand: function() {
|
||||
var that = this;
|
||||
RED.editor.editBuffer({
|
||||
@@ -108,12 +114,12 @@
|
||||
env: {
|
||||
value: "env",
|
||||
label: "env variable",
|
||||
icon: "red/images/typedInput/env.png"
|
||||
icon: "red/images/typedInput/env.svg"
|
||||
},
|
||||
node: {
|
||||
value: "node",
|
||||
label: "node",
|
||||
icon: "red/images/typedInput/target.png",
|
||||
icon: "red/images/typedInput/target.svg",
|
||||
valueLabel: function(container,value) {
|
||||
var node = RED.nodes.node(value);
|
||||
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).css({
|
||||
@@ -209,7 +215,7 @@
|
||||
that.input.css("margin"+d,0);
|
||||
});
|
||||
|
||||
["type","placeholder"].forEach(function(d) {
|
||||
["type","placeholder","autocomplete","data-i18n"].forEach(function(d) {
|
||||
var m = that.element.attr(d);
|
||||
that.input.attr(d,m);
|
||||
});
|
||||
@@ -225,6 +231,8 @@
|
||||
|
||||
this.selectLabel = $('<span class="red-ui-typedInput-type-label"></span>').appendTo(this.selectTrigger);
|
||||
|
||||
this.valueLabelContainer = $('<div class="red-ui-typedInput-value-label">').appendTo(this.uiSelect)
|
||||
|
||||
this.types(this.options.types);
|
||||
|
||||
if (this.options.typeField) {
|
||||
@@ -247,9 +255,15 @@
|
||||
that.validate();
|
||||
that.element.val(that.value());
|
||||
that.element.trigger('change',that.propertyType,that.value());
|
||||
});
|
||||
this.input.on('keydown', function(evt) {
|
||||
if (evt.keyCode >= 37 && evt.keyCode <= 40) {
|
||||
evt.stopPropagation();
|
||||
}
|
||||
})
|
||||
this.selectTrigger.on("click", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
that._showTypeMenu();
|
||||
});
|
||||
this.selectTrigger.on('keydown',function(evt) {
|
||||
@@ -257,12 +271,11 @@
|
||||
// Down
|
||||
that._showTypeMenu();
|
||||
}
|
||||
evt.stopPropagation();
|
||||
}).on('focus', function() {
|
||||
that.uiSelect.addClass('red-ui-typedInput-focus');
|
||||
})
|
||||
|
||||
this.valueLabelContainer = $('<div class="red-ui-typedInput-value-label">').appendTo(this.uiSelect)
|
||||
|
||||
// explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline'
|
||||
this.optionSelectTrigger = $('<button tabindex="0" class="red-ui-typedInput-option-trigger" style="display:inline-block"><span class="red-ui-typedInput-option-caret"><i class="red-ui-typedInput-icon fa fa-caret-down"></i></span></button>').appendTo(this.uiSelect);
|
||||
this.optionSelectLabel = $('<span class="red-ui-typedInput-option-label"></span>').prependTo(this.optionSelectTrigger);
|
||||
@@ -271,19 +284,22 @@
|
||||
});
|
||||
this.optionSelectTrigger.on("click", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
that._showOptionSelectMenu();
|
||||
}).on('keydown', function(evt) {
|
||||
if (evt.keyCode === 40) {
|
||||
// Down
|
||||
that._showOptionSelectMenu();
|
||||
}
|
||||
evt.stopPropagation();
|
||||
}).on('blur', function() {
|
||||
that.uiSelect.removeClass('red-ui-typedInput-focus');
|
||||
}).on('focus', function() {
|
||||
that.uiSelect.addClass('red-ui-typedInput-focus');
|
||||
});
|
||||
|
||||
this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"><i class="red-ui-typedInput-icon fa fa-ellipsis-h"></i></button>').appendTo(this.uiSelect);
|
||||
this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"></button>').appendTo(this.uiSelect);
|
||||
this.optionExpandButtonIcon = $('<i class="red-ui-typedInput-icon fa fa-ellipsis-h"></i>').appendTo(this.optionExpandButton);
|
||||
this.type(this.options.default||this.typeList[0].value);
|
||||
}catch(err) {
|
||||
console.log(err.stack);
|
||||
@@ -321,6 +337,17 @@
|
||||
menu.css({
|
||||
height: "auto"
|
||||
});
|
||||
|
||||
if (menu.opts.multiple) {
|
||||
var selected = [];
|
||||
menu.find('input[type="checkbox"]').each(function() {
|
||||
if ($(this).prop("checked")) {
|
||||
selected.push($(this).data('value'))
|
||||
}
|
||||
})
|
||||
menu.callback(selected);
|
||||
}
|
||||
|
||||
if (this.elementDiv.is(":visible")) {
|
||||
this.input.trigger("focus");
|
||||
} else if (this.optionSelectTrigger.is(":visible")){
|
||||
@@ -329,10 +356,12 @@
|
||||
this.selectTrigger.trigger("focus");
|
||||
}
|
||||
},
|
||||
_createMenu: function(opts,callback) {
|
||||
_createMenu: function(menuOptions,opts,callback) {
|
||||
var that = this;
|
||||
var menu = $("<div>").addClass("red-ui-typedInput-options");
|
||||
opts.forEach(function(opt) {
|
||||
var menu = $("<div>").addClass("red-ui-typedInput-options red-ui-editor-dialog");
|
||||
menu.opts = opts;
|
||||
menu.callback = callback;
|
||||
menuOptions.forEach(function(opt) {
|
||||
if (typeof opt === 'string') {
|
||||
opt = {value:opt,label:opt};
|
||||
}
|
||||
@@ -344,7 +373,7 @@
|
||||
if (opt.icon.indexOf("<") === 0) {
|
||||
$(opt.icon).prependTo(op);
|
||||
} else if (opt.icon.indexOf("/") !== -1) {
|
||||
$('<img>',{src:opt.icon,style:"margin-right: 4px; height: 18px;"}).prependTo(op);
|
||||
$('<img>',{src:mapDeprecatedIcon(opt.icon),style:"margin-right: 4px; height: 18px;"}).prependTo(op);
|
||||
} else {
|
||||
$('<i>',{class:"red-ui-typedInput-icon "+opt.icon}).prependTo(op);
|
||||
}
|
||||
@@ -354,11 +383,20 @@
|
||||
if (!opt.icon && !opt.label) {
|
||||
op.text(opt.value);
|
||||
}
|
||||
var cb;
|
||||
if (opts.multiple) {
|
||||
cb = $('<input type="checkbox">').css("pointer-events","none").data('value',opt.value).prependTo(op).on("mousedown", function(evt) { evt.preventDefault() });
|
||||
}
|
||||
|
||||
op.on("click", function(event) {
|
||||
event.preventDefault();
|
||||
callback(opt.value);
|
||||
that._hideMenu(menu);
|
||||
event.stopPropagation();
|
||||
if (!opts.multiple) {
|
||||
callback(opt.value);
|
||||
that._hideMenu(menu);
|
||||
} else {
|
||||
cb.prop("checked",!cb.prop("checked"));
|
||||
}
|
||||
});
|
||||
});
|
||||
menu.css({
|
||||
@@ -376,13 +414,12 @@
|
||||
// UP
|
||||
$(this).children(":focus").prev().trigger("focus");
|
||||
} else if (evt.keyCode === 27) {
|
||||
// ESCAPE
|
||||
evt.preventDefault();
|
||||
that._hideMenu(menu);
|
||||
}
|
||||
evt.stopPropagation();
|
||||
})
|
||||
|
||||
|
||||
|
||||
return menu;
|
||||
|
||||
},
|
||||
@@ -391,11 +428,22 @@
|
||||
this.disarmClick = false;
|
||||
return
|
||||
}
|
||||
if (menu.opts.multiple) {
|
||||
var selected = {};
|
||||
this.value().split(",").forEach(function(f) {
|
||||
selected[f] = true;
|
||||
})
|
||||
menu.find('input[type="checkbox"]').each(function() {
|
||||
$(this).prop("checked",selected[$(this).data('value')])
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
var that = this;
|
||||
var pos = relativeTo.offset();
|
||||
var height = relativeTo.height();
|
||||
var menuHeight = menu.height();
|
||||
var top = (height+pos.top-3);
|
||||
var top = (height+pos.top);
|
||||
if (top+menuHeight > $(window).height()) {
|
||||
top -= (top+menuHeight)-$(window).height()+5;
|
||||
}
|
||||
@@ -405,7 +453,7 @@
|
||||
}
|
||||
menu.css({
|
||||
top: top+"px",
|
||||
left: (2+pos.left)+"px",
|
||||
left: (pos.left)+"px",
|
||||
});
|
||||
menu.slideDown(100);
|
||||
this._delay(function() {
|
||||
@@ -421,20 +469,27 @@
|
||||
})
|
||||
});
|
||||
},
|
||||
_getLabelWidth: function(label) {
|
||||
_getLabelWidth: function(label, done) {
|
||||
var labelWidth = label.outerWidth();
|
||||
if (labelWidth === 0) {
|
||||
var container = $('<div class="red-ui-typedInput-container"></div>').css({
|
||||
var wrapper = $('<div class="red-ui-editor"></div>').css({
|
||||
position:"absolute",
|
||||
top:0
|
||||
"white-space": "nowrap",
|
||||
top:-2000
|
||||
}).appendTo(document.body);
|
||||
var container = $('<div class="red-ui-typedInput-container"></div>').appendTo(wrapper);
|
||||
var newTrigger = label.clone().appendTo(container);
|
||||
labelWidth = newTrigger.outerWidth();
|
||||
container.remove();
|
||||
setTimeout(function() {
|
||||
labelWidth = newTrigger.outerWidth();
|
||||
wrapper.remove();
|
||||
done(labelWidth);
|
||||
},50)
|
||||
} else {
|
||||
done(labelWidth);
|
||||
}
|
||||
return labelWidth;
|
||||
},
|
||||
_resize: function() {
|
||||
var that = this;
|
||||
if (this.uiWidth !== null) {
|
||||
this.uiSelect.width(this.uiWidth);
|
||||
}
|
||||
@@ -443,71 +498,78 @@
|
||||
this.selectTrigger.addClass("red-ui-typedInput-full-width");
|
||||
} else {
|
||||
this.selectTrigger.removeClass("red-ui-typedInput-full-width");
|
||||
var labelWidth = this._getLabelWidth(this.selectTrigger);
|
||||
this.elementDiv.css('left',labelWidth+"px");
|
||||
this.valueLabelContainer.css('left',labelWidth+"px");
|
||||
if (this.optionExpandButton.is(":visible")) {
|
||||
this.elementDiv.css('right',"22px");
|
||||
this.valueLabelContainer.css('right',"22px");
|
||||
} else {
|
||||
this.elementDiv.css('right','0');
|
||||
this.valueLabelContainer.css('right','0');
|
||||
this.input.css({
|
||||
'border-top-right-radius': '4px',
|
||||
'border-bottom-right-radius': '4px'
|
||||
});
|
||||
}
|
||||
|
||||
// if (this.optionSelectTrigger) {
|
||||
// this.optionSelectTrigger.css({'left':(labelWidth)+"px",'width':'calc( 100% - '+labelWidth+'px )'});
|
||||
// }
|
||||
|
||||
if (this.optionSelectTrigger) {
|
||||
if (type && type.options && type.hasValue === true) {
|
||||
this.optionSelectLabel.css({'left':'auto'})
|
||||
var lw = this._getLabelWidth(this.optionSelectLabel);
|
||||
this.optionSelectTrigger.css({'width':(23+lw)+"px"});
|
||||
this.elementDiv.css('right',(23+lw)+"px");
|
||||
this.input.css({
|
||||
'border-top-right-radius': 0,
|
||||
'border-bottom-right-radius': 0
|
||||
});
|
||||
this._getLabelWidth(this.selectTrigger, function(labelWidth) {
|
||||
that.elementDiv.css('left',labelWidth+"px");
|
||||
that.valueLabelContainer.css('left',labelWidth+"px");
|
||||
if (that.optionExpandButton.shown) {
|
||||
that.elementDiv.css('right',"22px");
|
||||
that.valueLabelContainer.css('right',"22px");
|
||||
} else {
|
||||
this.optionSelectLabel.css({'left':'0'})
|
||||
this.optionSelectTrigger.css({'width':'calc( 100% - '+labelWidth+'px )'});
|
||||
if (!this.optionExpandButton.is(":visible")) {
|
||||
this.elementDiv.css({'right':0});
|
||||
this.input.css({
|
||||
'border-top-right-radius': '4px',
|
||||
'border-bottom-right-radius': '4px'
|
||||
that.elementDiv.css('right','0');
|
||||
that.valueLabelContainer.css('right','0');
|
||||
that.input.css({
|
||||
'border-top-right-radius': '4px',
|
||||
'border-bottom-right-radius': '4px'
|
||||
});
|
||||
}
|
||||
if (that.optionSelectTrigger) {
|
||||
if (type && type.options && type.hasValue === true) {
|
||||
that.optionSelectLabel.css({'left':'auto'})
|
||||
that._getLabelWidth(that.optionSelectLabel, function(lw) {
|
||||
that.optionSelectTrigger.css({'width':(23+lw)+"px"});
|
||||
that.elementDiv.css('right',(23+lw)+"px");
|
||||
that.input.css({
|
||||
'border-top-right-radius': 0,
|
||||
'border-bottom-right-radius': 0
|
||||
});
|
||||
});
|
||||
} else {
|
||||
that.optionSelectLabel.css({'left':'0'})
|
||||
that.optionSelectTrigger.css({'width':'calc( 100% - '+labelWidth+'px )'});
|
||||
if (!that.optionExpandButton.shown) {
|
||||
that.elementDiv.css({'right':0});
|
||||
that.input.css({
|
||||
'border-top-right-radius': '4px',
|
||||
'border-bottom-right-radius': '4px'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
_updateOptionSelectLabel: function(o) {
|
||||
var opt = this.typeMap[this.propertyType];
|
||||
this.optionSelectLabel.empty();
|
||||
if (o.icon) {
|
||||
if (o.icon.indexOf("<") === 0) {
|
||||
$(o.icon).prependTo(this.optionSelectLabel);
|
||||
} else if (o.icon.indexOf("/") !== -1) {
|
||||
// url
|
||||
$('<img>',{src:o.icon,style:"height: 18px;"}).prependTo(this.optionSelectLabel);
|
||||
if (this.typeMap[this.propertyType].valueLabel) {
|
||||
if (opt.multiple) {
|
||||
this.typeMap[this.propertyType].valueLabel.call(this,this.optionSelectLabel,o);
|
||||
} else {
|
||||
// icon class
|
||||
$('<i>',{class:"red-ui-typedInput-icon "+o.icon}).prependTo(this.optionSelectLabel);
|
||||
this.typeMap[this.propertyType].valueLabel.call(this,this.optionSelectLabel,o.value);
|
||||
}
|
||||
} else if (!opt.multiple) {
|
||||
if (o.icon) {
|
||||
if (o.icon.indexOf("<") === 0) {
|
||||
$(o.icon).prependTo(this.optionSelectLabel);
|
||||
} else if (o.icon.indexOf("/") !== -1) {
|
||||
// url
|
||||
$('<img>',{src:mapDeprecatedIcon(o.icon),style:"height: 18px;"}).prependTo(this.optionSelectLabel);
|
||||
} else {
|
||||
// icon class
|
||||
$('<i>',{class:"red-ui-typedInput-icon "+o.icon}).prependTo(this.optionSelectLabel);
|
||||
}
|
||||
} else if (o.label) {
|
||||
this.optionSelectLabel.text(o.label);
|
||||
} else {
|
||||
this.optionSelectLabel.text(o.value);
|
||||
}
|
||||
if (opt.hasValue) {
|
||||
this.optionValue = o.value;
|
||||
this._resize();
|
||||
this.input.trigger('change',this.propertyType,this.value());
|
||||
}
|
||||
} else if (o.label) {
|
||||
this.optionSelectLabel.text(o.label);
|
||||
} else {
|
||||
this.optionSelectLabel.text(o.value);
|
||||
}
|
||||
if (opt.hasValue) {
|
||||
this.optionValue = o.value;
|
||||
this._resize();
|
||||
this.input.trigger('change',this.propertyType,this.value());
|
||||
this.optionSelectLabel.text(o.length+" selected");
|
||||
}
|
||||
},
|
||||
_destroy: function() {
|
||||
@@ -515,6 +577,7 @@
|
||||
this.optionMenu.remove();
|
||||
}
|
||||
this.menu.remove();
|
||||
this.uiSelect.remove();
|
||||
},
|
||||
types: function(types) {
|
||||
var that = this;
|
||||
@@ -535,7 +598,7 @@
|
||||
if (this.menu) {
|
||||
this.menu.remove();
|
||||
}
|
||||
this.menu = this._createMenu(this.typeList, function(v) { that.type(v) });
|
||||
this.menu = this._createMenu(this.typeList,{},function(v) { that.type(v) });
|
||||
if (currentType && !this.typeMap.hasOwnProperty(currentType)) {
|
||||
this.type(this.typeList[0].value);
|
||||
} else {
|
||||
@@ -549,37 +612,51 @@
|
||||
this._resize();
|
||||
},
|
||||
value: function(value) {
|
||||
var that = this;
|
||||
var opt = this.typeMap[this.propertyType];
|
||||
if (!arguments.length) {
|
||||
var v = this.input.val();
|
||||
if (this.typeMap[this.propertyType].export) {
|
||||
v = this.typeMap[this.propertyType].export(v,this.optionValue)
|
||||
if (opt.export) {
|
||||
v = opt.export(v,this.optionValue)
|
||||
}
|
||||
return v;
|
||||
} else {
|
||||
var selectedOption;
|
||||
if (this.typeMap[this.propertyType].options) {
|
||||
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) {
|
||||
selectedOption = this.activeOptions[op];
|
||||
var selectedOption = [];
|
||||
if (opt.options) {
|
||||
var checkValues = [value];
|
||||
if (opt.multiple) {
|
||||
selectedOption = [];
|
||||
checkValues = value.split(",");
|
||||
}
|
||||
checkValues.forEach(function(value) {
|
||||
for (var i=0;i<opt.options.length;i++) {
|
||||
var op = opt.options[i];
|
||||
if (typeof op === "string") {
|
||||
if (op === value || op === ""+value) {
|
||||
selectedOption.push(that.activeOptions[op]);
|
||||
break;
|
||||
}
|
||||
} else if (op.value === value) {
|
||||
selectedOption.push(op);
|
||||
break;
|
||||
}
|
||||
} else if (op.value === value) {
|
||||
selectedOption = op;
|
||||
break;
|
||||
}
|
||||
})
|
||||
this.input.val(value);
|
||||
if (!opt.multiple) {
|
||||
if (selectedOption.length === 0) {
|
||||
selectedOption = [{value:""}];
|
||||
}
|
||||
this._updateOptionSelectLabel(selectedOption[0])
|
||||
} else {
|
||||
this._updateOptionSelectLabel(selectedOption)
|
||||
}
|
||||
if (!selectedOption) {
|
||||
selectedOption = {value:""}
|
||||
}
|
||||
this._updateOptionSelectLabel(selectedOption)
|
||||
} else {
|
||||
this.input.val(value);
|
||||
}
|
||||
if (this.typeMap[this.propertyType].valueLabel) {
|
||||
this.valueLabelContainer.empty();
|
||||
this.typeMap[this.propertyType].valueLabel.call(this,this.valueLabelContainer,value);
|
||||
if (opt.valueLabel) {
|
||||
this.valueLabelContainer.empty();
|
||||
opt.valueLabel.call(this,this.valueLabelContainer,value);
|
||||
}
|
||||
}
|
||||
this.input.trigger('change',this.type(),value);
|
||||
}
|
||||
@@ -597,20 +674,23 @@
|
||||
}
|
||||
this.selectLabel.empty();
|
||||
var image;
|
||||
if (opt.icon) {
|
||||
if (opt.icon && opt.showLabel !== false) {
|
||||
if (opt.icon.indexOf("<") === 0) {
|
||||
$(opt.icon).prependTo(this.selectLabel);
|
||||
}
|
||||
else if (opt.icon.indexOf("/") !== -1) {
|
||||
image = new Image();
|
||||
image.onload = function() { that._resize(); }
|
||||
image.onerror = function() { that._resize(); }
|
||||
image.name = opt.icon;
|
||||
image.src = opt.icon;
|
||||
$('<img>',{src:opt.icon,style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel);
|
||||
image.src = mapDeprecatedIcon(opt.icon);
|
||||
$('<img>',{src:mapDeprecatedIcon(opt.icon),style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel);
|
||||
}
|
||||
else {
|
||||
$('<i>',{class:"red-ui-typedInput-icon "+opt.icon}).prependTo(this.selectLabel);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if (opt.hasValue === false || (opt.showLabel !== false && !opt.icon)) {
|
||||
this.selectLabel.text(opt.label);
|
||||
}
|
||||
if (this.optionMenu) {
|
||||
@@ -620,6 +700,7 @@
|
||||
if (opt.options) {
|
||||
if (this.optionExpandButton) {
|
||||
this.optionExpandButton.hide();
|
||||
this.optionExpandButton.shown = false;
|
||||
}
|
||||
if (this.optionSelectTrigger) {
|
||||
this.optionSelectTrigger.show();
|
||||
@@ -642,36 +723,50 @@
|
||||
if (!that.activeOptions.hasOwnProperty(that.optionValue)) {
|
||||
that.optionValue = null;
|
||||
}
|
||||
this.optionMenu = this._createMenu(opt.options,function(v){
|
||||
that._updateOptionSelectLabel(that.activeOptions[v]);
|
||||
if (!opt.hasValue) {
|
||||
that.value(that.activeOptions[v].value)
|
||||
}
|
||||
});
|
||||
|
||||
var op;
|
||||
if (!opt.hasValue) {
|
||||
var currentVal = this.input.val();
|
||||
var validValue = false;
|
||||
for (var i=0;i<opt.options.length;i++) {
|
||||
op = opt.options[i];
|
||||
if (typeof op === "string" && op === currentVal) {
|
||||
that._updateOptionSelectLabel({value:currentVal});
|
||||
validValue = true;
|
||||
break;
|
||||
} else if (op.value === currentVal) {
|
||||
that._updateOptionSelectLabel(op);
|
||||
validValue = true;
|
||||
break;
|
||||
var currentVal = this.input.val();
|
||||
if (!opt.multiple) {
|
||||
for (var i=0;i<opt.options.length;i++) {
|
||||
op = opt.options[i];
|
||||
if (typeof op === "string" && op === currentVal) {
|
||||
that._updateOptionSelectLabel({value:currentVal});
|
||||
validValue = true;
|
||||
break;
|
||||
} else if (op.value === currentVal) {
|
||||
that._updateOptionSelectLabel(op);
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!validValue) {
|
||||
op = opt.options[0];
|
||||
if (typeof op === "string") {
|
||||
this.value(op);
|
||||
that._updateOptionSelectLabel({value:op});
|
||||
} else {
|
||||
this.value(op.value);
|
||||
that._updateOptionSelectLabel(op);
|
||||
if (!validValue) {
|
||||
op = opt.options[0];
|
||||
if (typeof op === "string") {
|
||||
this.value(op);
|
||||
that._updateOptionSelectLabel({value:op});
|
||||
} else {
|
||||
this.value(op.value);
|
||||
that._updateOptionSelectLabel(op);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check to see if value is a valid csv of
|
||||
// options.
|
||||
var currentValues = {};
|
||||
currentVal.split(",").forEach(function(v) {
|
||||
if (v) {
|
||||
currentValues[v] = true;
|
||||
}
|
||||
});
|
||||
for (var i=0;i<opt.options.length;i++) {
|
||||
op = opt.options[i];
|
||||
delete currentValues[op.value||op];
|
||||
}
|
||||
if (!$.isEmptyObject(currentValues)) {
|
||||
// Invalid, set to default/empty
|
||||
this.value((opt.default||[]).join(","));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -707,7 +802,21 @@
|
||||
this.optionSelectTrigger.hide();
|
||||
}
|
||||
}
|
||||
this.optionMenu = this._createMenu(opt.options,opt,function(v){
|
||||
if (!opt.multiple) {
|
||||
that._updateOptionSelectLabel(that.activeOptions[v]);
|
||||
if (!opt.hasValue) {
|
||||
that.value(that.activeOptions[v].value)
|
||||
}
|
||||
} else {
|
||||
that._updateOptionSelectLabel(v);
|
||||
if (!opt.hasValue) {
|
||||
that.value(v.join(","))
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
this._trigger("typechange",null,this.propertyType);
|
||||
this.input.trigger('change',this.propertyType,this.value());
|
||||
} else {
|
||||
if (this.optionSelectTrigger) {
|
||||
@@ -732,23 +841,47 @@
|
||||
this.elementDiv.show();
|
||||
}
|
||||
if (this.optionExpandButton) {
|
||||
if (opt.expand && typeof opt.expand === 'function') {
|
||||
if (opt.expand) {
|
||||
if (opt.expand.icon) {
|
||||
this.optionExpandButtonIcon.removeClass().addClass("red-ui-typedInput-icon fa "+opt.expand.icon)
|
||||
} else {
|
||||
this.optionExpandButtonIcon.removeClass().addClass("red-ui-typedInput-icon fa fa-ellipsis-h")
|
||||
}
|
||||
this.optionExpandButton.shown = true;
|
||||
this.optionExpandButton.show();
|
||||
this.optionExpandButton.off('click');
|
||||
this.optionExpandButton.on('click',function(evt) {
|
||||
evt.preventDefault();
|
||||
opt.expand.call(that);
|
||||
if (typeof opt.expand === 'function') {
|
||||
opt.expand.call(that);
|
||||
} else {
|
||||
var container = $('<div>');
|
||||
var content = opt.expand.content.call(that,container);
|
||||
var panel = RED.popover.panel(container);
|
||||
panel.container.css({
|
||||
width:that.valueLabelContainer.width()
|
||||
});
|
||||
if (opt.expand.minWidth) {
|
||||
panel.container.css({
|
||||
minWidth: opt.expand.minWidth+"px"
|
||||
});
|
||||
}
|
||||
panel.show({
|
||||
target:that.optionExpandButton,
|
||||
onclose:content.onclose,
|
||||
align: "right"
|
||||
});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.optionExpandButton.shown = false;
|
||||
this.optionExpandButton.hide();
|
||||
}
|
||||
}
|
||||
this._trigger("typechange",null,this.propertyType);
|
||||
this.input.trigger('change',this.propertyType,this.value());
|
||||
}
|
||||
if (image) {
|
||||
image.onload = function() { that._resize(); }
|
||||
image.onerror = function() { that._resize(); }
|
||||
} else {
|
||||
if (!image) {
|
||||
this._resize();
|
||||
}
|
||||
}
|
||||
|
@@ -17,9 +17,9 @@
|
||||
RED.deploy = (function() {
|
||||
|
||||
var deploymentTypes = {
|
||||
"full":{img:"red/images/deploy-full-o.png"},
|
||||
"nodes":{img:"red/images/deploy-nodes-o.png"},
|
||||
"flows":{img:"red/images/deploy-flows-o.png"}
|
||||
"full":{img:"red/images/deploy-full-o.svg"},
|
||||
"nodes":{img:"red/images/deploy-nodes-o.svg"},
|
||||
"flows":{img:"red/images/deploy-flows-o.svg"}
|
||||
}
|
||||
|
||||
var ignoreDeployWarnings = {
|
||||
@@ -44,7 +44,7 @@ RED.deploy = (function() {
|
||||
* type: "default" - Button with drop-down options - no further customisation available
|
||||
* type: "simple" - Button without dropdown. Customisations:
|
||||
* label: the text to display - default: "Deploy"
|
||||
* icon : the icon to use. Null removes the icon. default: "red/images/deploy-full-o.png"
|
||||
* icon : the icon to use. Null removes the icon. default: "red/images/deploy-full-o.svg"
|
||||
*/
|
||||
function init(options) {
|
||||
options = options || {};
|
||||
@@ -54,7 +54,7 @@ RED.deploy = (function() {
|
||||
$('<li><span class="red-ui-deploy-button-group button-group">'+
|
||||
'<a id="red-ui-header-button-deploy" class="red-ui-deploy-button disabled" href="#">'+
|
||||
'<span class="red-ui-deploy-button-content">'+
|
||||
'<img id="red-ui-header-button-deploy-icon" src="red/images/deploy-full-o.png"> '+
|
||||
'<img id="red-ui-header-button-deploy-icon" src="red/images/deploy-full-o.svg"> '+
|
||||
'<span>'+RED._("deploy.deploy")+'</span>'+
|
||||
'</span>'+
|
||||
'<span class="red-ui-deploy-button-spinner hide">'+
|
||||
@@ -65,17 +65,17 @@ RED.deploy = (function() {
|
||||
'</span></li>').prependTo(".red-ui-header-toolbar");
|
||||
RED.menu.init({id:"red-ui-header-button-deploy-options",
|
||||
options: [
|
||||
{id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.png",label:RED._("deploy.full"),sublabel:RED._("deploy.fullDesc"),selected: true, onselect:function(s) { if(s){changeDeploymentType("full")}}},
|
||||
{id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.png",label:RED._("deploy.modifiedFlows"),sublabel:RED._("deploy.modifiedFlowsDesc"), onselect:function(s) {if(s){changeDeploymentType("flows")}}},
|
||||
{id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.png",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}},
|
||||
{id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.svg",label:RED._("deploy.full"),sublabel:RED._("deploy.fullDesc"),selected: true, onselect:function(s) { if(s){changeDeploymentType("full")}}},
|
||||
{id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.svg",label:RED._("deploy.modifiedFlows"),sublabel:RED._("deploy.modifiedFlowsDesc"), onselect:function(s) {if(s){changeDeploymentType("flows")}}},
|
||||
{id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.svg",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}},
|
||||
null,
|
||||
{id:"deploymenu-item-reload", icon:"red/images/deploy-reload.png",label:RED._("deploy.restartFlows"),sublabel:RED._("deploy.restartFlowsDesc"),onselect:"core:restart-flows"},
|
||||
{id:"deploymenu-item-reload", icon:"red/images/deploy-reload.svg",label:RED._("deploy.restartFlows"),sublabel:RED._("deploy.restartFlowsDesc"),onselect:"core:restart-flows"},
|
||||
|
||||
]
|
||||
});
|
||||
} else if (type == "simple") {
|
||||
var label = options.label || RED._("deploy.deploy");
|
||||
var icon = 'red/images/deploy-full-o.png';
|
||||
var icon = 'red/images/deploy-full-o.svg';
|
||||
if (options.hasOwnProperty('icon')) {
|
||||
icon = options.icon;
|
||||
}
|
||||
@@ -99,7 +99,13 @@ RED.deploy = (function() {
|
||||
});
|
||||
|
||||
RED.actions.add("core:deploy-flows",save);
|
||||
RED.actions.add("core:restart-flows",restart);
|
||||
if (type === "default") {
|
||||
RED.actions.add("core:restart-flows",restart);
|
||||
RED.actions.add("core:set-deploy-type-to-full",function() { RED.menu.setSelected("deploymenu-item-full",true);});
|
||||
RED.actions.add("core:set-deploy-type-to-modified-flows",function() { RED.menu.setSelected("deploymenu-item-flow",true); });
|
||||
RED.actions.add("core:set-deploy-type-to-modified-nodes",function() { RED.menu.setSelected("deploymenu-item-node",true); });
|
||||
}
|
||||
|
||||
|
||||
|
||||
RED.events.on('nodes:change',function(state) {
|
||||
|
@@ -399,9 +399,9 @@ RED.diff = (function() {
|
||||
diff: localDiff,
|
||||
def: {
|
||||
defaults:{},
|
||||
icon:"subflow.png",
|
||||
icon:"subflow.svg",
|
||||
category: "subflows",
|
||||
color: "#da9"
|
||||
color: "#DDAA99"
|
||||
},
|
||||
tab:currentConfig.subflows[subflowId]
|
||||
}
|
||||
@@ -422,9 +422,9 @@ RED.diff = (function() {
|
||||
diff: localDiff,
|
||||
def: {
|
||||
defaults:{},
|
||||
icon:"subflow.png",
|
||||
icon:"subflow.svg",
|
||||
category: "subflows",
|
||||
color: "#da9"
|
||||
color: "#DDAA99"
|
||||
},
|
||||
tab:newConfig.subflows[subflowId],
|
||||
newTab:newConfig.subflows[subflowId]
|
||||
@@ -443,9 +443,9 @@ RED.diff = (function() {
|
||||
remoteDiff: remoteDiff,
|
||||
def: {
|
||||
defaults:{},
|
||||
icon:"subflow.png",
|
||||
icon:"subflow.svg",
|
||||
category: "subflows",
|
||||
color: "#da9"
|
||||
color: "#DDAA99"
|
||||
},
|
||||
tab:remoteDiff.newConfig.subflows[subflowId],
|
||||
remoteTab: remoteDiff.newConfig.subflows[subflowId]
|
||||
@@ -549,9 +549,9 @@ RED.diff = (function() {
|
||||
if (def === undefined) {
|
||||
if (/^subflow:/.test(node.type)) {
|
||||
def = {
|
||||
icon:"subflow.png",
|
||||
icon:"subflow.svg",
|
||||
category: "subflows",
|
||||
color: "#da9",
|
||||
color: "#DDAA99",
|
||||
defaults:{name:{value:""}}
|
||||
}
|
||||
} else {
|
||||
@@ -1029,9 +1029,9 @@ RED.diff = (function() {
|
||||
}
|
||||
|
||||
var localSelectDiv = $('<label>',{class:"red-ui-diff-selectbox",for:safeNodeId+"-local"}).on("click", function(e) { e.stopPropagation();}).appendTo(localDiv);
|
||||
var localRadio = $('<input>',{class:"red-ui-diff-selectbox-input",id:safeNodeId+"-local",type:'radio',value:"local",name:safeNodeId,class:className+"-local"}).data('node-id',node.id).on("change", changeHandler).appendTo(localSelectDiv);
|
||||
var localRadio = $('<input>',{class:"red-ui-diff-selectbox-input "+className+"-local",id:safeNodeId+"-local",type:'radio',value:"local",name:safeNodeId}).data('node-id',node.id).on("change", changeHandler).appendTo(localSelectDiv);
|
||||
var remoteSelectDiv = $('<label>',{class:"red-ui-diff-selectbox",for:safeNodeId+"-remote"}).on("click", function(e) { e.stopPropagation();}).appendTo(remoteDiv);
|
||||
var remoteRadio = $('<input>',{class:"red-ui-diff-selectbox-input",id:safeNodeId+"-remote",type:'radio',value:"remote",name:safeNodeId,class:className+"-remote"}).data('node-id',node.id).on("change", changeHandler).appendTo(remoteSelectDiv);
|
||||
var remoteRadio = $('<input>',{class:"red-ui-diff-selectbox-input "+className+"-remote",id:safeNodeId+"-remote",type:'radio',value:"remote",name:safeNodeId}).data('node-id',node.id).on("change", changeHandler).appendTo(remoteSelectDiv);
|
||||
if (state === 'local') {
|
||||
localRadio.prop('checked',true);
|
||||
} else if (state === 'remote') {
|
||||
|
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
RED.editor = (function() {
|
||||
|
||||
|
||||
var editStack = [];
|
||||
var editing_node = null;
|
||||
var editing_config_node = null;
|
||||
@@ -203,6 +202,7 @@ RED.editor = (function() {
|
||||
function updateNodeProperties(node, outputMap) {
|
||||
node.resize = true;
|
||||
node.dirty = true;
|
||||
node.dirtyStatus = true;
|
||||
var removedLinks = [];
|
||||
if (node.ports) {
|
||||
if (outputMap) {
|
||||
@@ -231,8 +231,12 @@ RED.editor = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
node.inputs = Math.min(1,Math.max(0,parseInt(node.inputs)));
|
||||
if (isNaN(node.inputs)) {
|
||||
node.inputs = 0;
|
||||
}
|
||||
if (node.inputs === 0) {
|
||||
removedLinks.concat(RED.nodes.filterLinks({target:node}));
|
||||
removedLinks = removedLinks.concat(RED.nodes.filterLinks({target:node}));
|
||||
}
|
||||
for (var l=0;l<removedLinks.length;l++) {
|
||||
RED.nodes.removeLink(removedLinks[l]);
|
||||
@@ -526,7 +530,7 @@ RED.editor = (function() {
|
||||
} else if (node.type.indexOf("subflow:")===0) {
|
||||
var subflow = RED.nodes.subflow(node.type.substring(8));
|
||||
label = RED._("subflow.editSubflowInstance",{name:RED.utils.sanitize(subflow.name)})
|
||||
} else {
|
||||
} else if (node._def !== undefined) {
|
||||
if (typeof node._def.paletteLabel !== "undefined") {
|
||||
try {
|
||||
label = RED.utils.sanitize((typeof node._def.paletteLabel === "function" ? node._def.paletteLabel.call(node._def) : node._def.paletteLabel)||"");
|
||||
@@ -546,146 +550,7 @@ RED.editor = (function() {
|
||||
return label;
|
||||
}
|
||||
|
||||
function buildEnvForm(container, node) {
|
||||
var env_container = $('#node-input-env-container');
|
||||
env_container
|
||||
.css({
|
||||
'min-height':'150px',
|
||||
'min-width':'450px'
|
||||
})
|
||||
.editableList({
|
||||
addItem: function(container, i, opt) {
|
||||
var row = $('<div/>').appendTo(container);
|
||||
if (opt.parent) {
|
||||
$('<div/>', {
|
||||
class:"uneditable-input",
|
||||
style: "margin-left: 5px; width: calc(40% - 8px)",
|
||||
}).appendTo(row).text(opt.name);
|
||||
} else {
|
||||
$('<input/>', {
|
||||
class: "node-input-env-name",
|
||||
type: "text",
|
||||
style: "margin-left: 5px; width: calc(40% - 8px)",
|
||||
placeholder: RED._("common.label.name")
|
||||
}).appendTo(row).val(opt.name);
|
||||
}
|
||||
var valueField = $('<input/>',{
|
||||
class: "node-input-env-value",
|
||||
type: "text",
|
||||
style: "margin-left: 5px; width: calc(60% - 8px)"
|
||||
}).appendTo(row)
|
||||
|
||||
valueField.typedInput({default:'str',
|
||||
types:['str','num','bool','json','bin','env']
|
||||
});
|
||||
|
||||
valueField.typedInput('type', opt.parent?(opt.type||opt.parent.type):opt.type);
|
||||
valueField.typedInput('value', opt.parent?((opt.value !== undefined)?opt.value:opt.parent.value):opt.value);
|
||||
|
||||
var actionButton = $('<a/>',{href:"#",class:"red-ui-editableList-item-remove red-ui-button red-ui-button-small"}).appendTo(container);
|
||||
$('<i/>',{class:"fa "+(opt.parent?"fa-reply":"fa-remove")}).appendTo(actionButton);
|
||||
container.parent().addClass("red-ui-editableList-item-removable");
|
||||
if (opt.parent) {
|
||||
if ((opt.value !== undefined) && (opt.value !== opt.parent.value || opt.type !== opt.parent.type)) {
|
||||
actionButton.show();
|
||||
} else {
|
||||
actionButton.hide();
|
||||
}
|
||||
var restoreTip = RED.popover.tooltip(actionButton,RED._("subflow.env.restore"));
|
||||
valueField.on("change", function(evt) {
|
||||
var newType = valueField.typedInput('type');
|
||||
var newValue = valueField.typedInput('value');
|
||||
if (newType === opt.parent.type && newValue === opt.parent.value) {
|
||||
actionButton.hide();
|
||||
} else {
|
||||
actionButton.show();
|
||||
}
|
||||
})
|
||||
actionButton.on("click", function(evt) {
|
||||
evt.preventDefault();
|
||||
restoreTip.close();
|
||||
valueField.typedInput('type', opt.parent.type);
|
||||
valueField.typedInput('value', opt.parent.value);
|
||||
})
|
||||
} else {
|
||||
var removeTip = RED.popover.tooltip(actionButton,RED._("subflow.env.remove"));
|
||||
actionButton.on("click", function(evt) {
|
||||
evt.preventDefault();
|
||||
removeTip.close();
|
||||
container.parent().addClass("red-ui-editableList-item-deleting")
|
||||
container.fadeOut(300, function() {
|
||||
env_container.editableList('removeItem',opt);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
sortable: false,
|
||||
removable: false
|
||||
});
|
||||
var parentEnv = {};
|
||||
var envList = [];
|
||||
if (/^subflow:/.test(node.type)) {
|
||||
var subflowDef = RED.nodes.subflow(node.type.substring(8));
|
||||
if (subflowDef.env) {
|
||||
subflowDef.env.forEach(function(env) {
|
||||
var item = {
|
||||
name:env.name,
|
||||
parent: {
|
||||
type: env.type,
|
||||
value: env.value
|
||||
}
|
||||
}
|
||||
envList.push(item);
|
||||
parentEnv[env.name] = item;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (node.env) {
|
||||
for (var i = 0; i < node.env.length; i++) {
|
||||
var env = node.env[i];
|
||||
if (parentEnv.hasOwnProperty(env.name)) {
|
||||
parentEnv[env.name].type = env.type;
|
||||
parentEnv[env.name].value = env.value;
|
||||
} else {
|
||||
envList.push({
|
||||
name: env.name,
|
||||
type: env.type,
|
||||
value: env.value
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
envList.forEach(function(env) {
|
||||
env_container.editableList('addItem', env);
|
||||
})
|
||||
}
|
||||
|
||||
function exportEnvList(list) {
|
||||
if (list) {
|
||||
var env = [];
|
||||
list.each(function(i) {
|
||||
var entry = $(this);
|
||||
var item = entry.data('data');
|
||||
var name = item.parent?item.name:entry.find(".node-input-env-name").val();
|
||||
var valueInput = entry.find(".node-input-env-value");
|
||||
var value = valueInput.typedInput("value");
|
||||
var type = valueInput.typedInput("type");
|
||||
if (!item.parent || (item.parent.value !== value || item.parent.type !== type)) {
|
||||
var item = {
|
||||
name: name,
|
||||
type: type,
|
||||
value: value
|
||||
};
|
||||
env.push(item);
|
||||
}
|
||||
});
|
||||
return env;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function isSameEnv(env0, env1) {
|
||||
function isSameObj(env0, env1) {
|
||||
return (JSON.stringify(env0) === JSON.stringify(env1));
|
||||
}
|
||||
|
||||
@@ -711,8 +576,8 @@ RED.editor = (function() {
|
||||
$(this).attr("data-i18n",keys.join(";"));
|
||||
});
|
||||
|
||||
if ((type === "subflow") || (type === "subflow-template")) {
|
||||
buildEnvForm(dialogForm, node);
|
||||
if (type === "subflow-template" || type === "subflow") {
|
||||
RED.subflow.buildEditForm(dialogForm,type,node);
|
||||
}
|
||||
|
||||
// Add dummy fields to prevent 'Enter' submitting the form in some
|
||||
@@ -721,6 +586,7 @@ RED.editor = (function() {
|
||||
$('<input type="password" style="display: none;" />').prependTo(dialogForm);
|
||||
$('<input type="text" style="display: none;" />').prependTo(dialogForm);
|
||||
dialogForm.on("submit", function(e) { e.preventDefault();});
|
||||
dialogForm.find('input').attr("autocomplete","disable");
|
||||
return dialogForm;
|
||||
}
|
||||
|
||||
@@ -733,10 +599,18 @@ RED.editor = (function() {
|
||||
var outputsDiv = $("#red-ui-editor-node-label-form-outputs");
|
||||
|
||||
var inputCount;
|
||||
if (node.type === 'subflow') {
|
||||
inputCount = node.in.length;
|
||||
var formInputs = $("#node-input-inputs").val();
|
||||
if (formInputs === undefined) {
|
||||
if (node.type === 'subflow') {
|
||||
inputCount = node.in.length;
|
||||
} else {
|
||||
inputCount = node.inputs || node._def.inputs || 0;
|
||||
}
|
||||
} else {
|
||||
inputCount = node.inputs || node._def.inputs || 0;
|
||||
inputCount = Math.min(1,Math.max(0,parseInt(formInputs)));
|
||||
if (isNaN(inputCount)) {
|
||||
inputCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var children = inputsDiv.children();
|
||||
@@ -854,30 +728,8 @@ RED.editor = (function() {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function showIconPicker(container, node, iconPath, done) {
|
||||
var containerPos = container.offset();
|
||||
var pickerBackground = $('<div>').css({
|
||||
position: "absolute",top:0,bottom:0,left:0,right:0,zIndex:20
|
||||
}).appendTo("body");
|
||||
|
||||
var top = containerPos.top - 30;
|
||||
|
||||
if (top+280 > $( window ).height()) {
|
||||
top = $( window ).height() - 280;
|
||||
}
|
||||
var picker = $('<div class="red-ui-icon-picker">').css({
|
||||
top: top+"px",
|
||||
left: containerPos.left+"px",
|
||||
}).appendTo("#red-ui-editor");
|
||||
|
||||
var hide = function() {
|
||||
pickerBackground.remove();
|
||||
picker.remove();
|
||||
RED.keyboard.remove("escape");
|
||||
}
|
||||
RED.keyboard.add("*","escape",function(){hide()});
|
||||
pickerBackground.on("mousedown", hide);
|
||||
|
||||
function showIconPicker(container, backgroundColor, iconPath, faOnly, done) {
|
||||
var picker = $('<div class="red-ui-icon-picker">');
|
||||
var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(picker);
|
||||
searchInput = $('<input type="text">').attr("placeholder",RED._("editor.searchIcons")).appendTo(searchDiv).searchBox({
|
||||
delay: 50,
|
||||
@@ -905,89 +757,256 @@ RED.editor = (function() {
|
||||
var summary = $('<span>').appendTo(metaRow);
|
||||
var resetButton = $('<button type="button" class="red-ui-button red-ui-button-small">'+RED._("editor.useDefault")+'</button>').appendTo(metaRow).on("click", function(e) {
|
||||
e.preventDefault();
|
||||
hide();
|
||||
iconPanel.hide();
|
||||
done(null);
|
||||
});
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
Object.keys(iconSets).forEach(function(moduleName) {
|
||||
var icons = iconSets[moduleName];
|
||||
if (icons.length > 0) {
|
||||
// selectIconModule.append($("<option></option>").val(moduleName).text(moduleName));
|
||||
var header = $('<div class="red-ui-icon-list-module"></div>').text(moduleName).appendTo(iconList);
|
||||
$('<i class="fa fa-cube"></i>').prependTo(header);
|
||||
icons.forEach(function(icon) {
|
||||
var iconDiv = $('<div>',{class:"red-ui-icon-list-icon"}).appendTo(iconList);
|
||||
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconDiv);
|
||||
var colour = RED.utils.getNodeColor(node.type, node._def);
|
||||
var icon_url = RED.settings.apiRootUrl+"icons/"+moduleName+"/"+icon;
|
||||
iconDiv.data('icon',icon_url);
|
||||
nodeDiv.css('backgroundColor',colour);
|
||||
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||
if (!backgroundColor && faOnly) {
|
||||
iconList.addClass("red-ui-icon-list-dark");
|
||||
}
|
||||
setTimeout(function() {
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
Object.keys(iconSets).forEach(function(moduleName) {
|
||||
if (faOnly && (moduleName !== "font-awesome")) {
|
||||
return;
|
||||
}
|
||||
var icons = iconSets[moduleName];
|
||||
if (icons.length > 0) {
|
||||
// selectIconModule.append($("<option></option>").val(moduleName).text(moduleName));
|
||||
var header = $('<div class="red-ui-icon-list-module"></div>').text(moduleName).appendTo(iconList);
|
||||
$('<i class="fa fa-cube"></i>').prependTo(header);
|
||||
icons.forEach(function(icon) {
|
||||
var iconDiv = $('<div>',{class:"red-ui-icon-list-icon"}).appendTo(iconList);
|
||||
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconDiv);
|
||||
var icon_url = RED.settings.apiRootUrl+"icons/"+moduleName+"/"+icon;
|
||||
iconDiv.data('icon',icon_url);
|
||||
if (backgroundColor) {
|
||||
nodeDiv.css({
|
||||
'backgroundColor': backgroundColor
|
||||
});
|
||||
}
|
||||
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||
|
||||
if (iconPath.module === moduleName && iconPath.file === icon) {
|
||||
iconDiv.addClass("selected");
|
||||
}
|
||||
iconDiv.on("mouseover", function() {
|
||||
summary.text(icon);
|
||||
if (iconPath.module === moduleName && iconPath.file === icon) {
|
||||
iconDiv.addClass("selected");
|
||||
}
|
||||
iconDiv.on("mouseover", function() {
|
||||
summary.text(icon);
|
||||
})
|
||||
iconDiv.on("mouseout", function() {
|
||||
summary.html(" ");
|
||||
})
|
||||
iconDiv.on("click", function() {
|
||||
iconPanel.hide();
|
||||
done(moduleName+"/"+icon);
|
||||
})
|
||||
})
|
||||
iconDiv.on("mouseout", function() {
|
||||
summary.html(" ");
|
||||
})
|
||||
iconDiv.on("click", function() {
|
||||
hide();
|
||||
done(moduleName+"/"+icon);
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
setTimeout(function() {
|
||||
spinner.remove();
|
||||
},50);
|
||||
},300);
|
||||
var spinner = RED.utils.addSpinnerOverlay(iconList,true);
|
||||
var iconPanel = RED.popover.panel(picker);
|
||||
iconPanel.show({
|
||||
target: container
|
||||
})
|
||||
|
||||
|
||||
picker.slideDown(100);
|
||||
searchInput.trigger("focus");
|
||||
}
|
||||
|
||||
function createColorPicker(colorRow, color) {
|
||||
|
||||
var colorButton = $('<button type="button" class="red-ui-button red-ui-editor-node-appearance-button">').appendTo(colorRow);
|
||||
$('<i class="fa fa-caret-down"></i>').appendTo(colorButton);
|
||||
|
||||
var colorDisp = $('<div>',{class:"red-ui-search-result-node"}).appendTo(colorButton);
|
||||
|
||||
var selector = $("<input/>", {
|
||||
id: "red-ui-editor-node-color",
|
||||
type: "text",
|
||||
value: color
|
||||
}).css({
|
||||
marginLeft: "10px",
|
||||
width: "150px",
|
||||
}).appendTo(colorRow);
|
||||
|
||||
selector.on("change", function (e) {
|
||||
var color = selector.val();
|
||||
$(".red-ui-editor-node-appearance-button .red-ui-search-result-node").css({
|
||||
"background-color": color
|
||||
});
|
||||
});
|
||||
selector.trigger("change");
|
||||
colorButton.on("click", function (e) {
|
||||
var recommendedColors = [
|
||||
"#DDAA99",
|
||||
"#3FADB5", "#87A980", "#A6BBCF",
|
||||
"#AAAA66", "#C0C0C0", "#C0DEED",
|
||||
"#C7E9C0", "#D7D7A0", "#D8BFD8",
|
||||
"#DAC4B4", "#DEB887", "#DEBD5C",
|
||||
"#E2D96E", "#E6E0F8", "#E7E7AE",
|
||||
"#E9967A", "#F3B567", "#FDD0A2",
|
||||
"#FDF0C2", "#FFAAAA", "#FFCC66",
|
||||
"#FFF0F0", "#FFFFFF"
|
||||
].map(function(c) {
|
||||
var r = parseInt(c.substring(1, 3), 16) / 255;
|
||||
var g = parseInt(c.substring(3, 5), 16) / 255;
|
||||
var b = parseInt(c.substring(5, 7), 16) / 255;
|
||||
return {
|
||||
hex: c,
|
||||
r: r,
|
||||
g: g,
|
||||
b: b,
|
||||
l: 0.3 * r + 0.59 * g + 0.11 * b
|
||||
}
|
||||
});
|
||||
// Sort by luminosity.
|
||||
recommendedColors.sort(function (a, b) {
|
||||
return a.l - b.l;
|
||||
});
|
||||
|
||||
var numColors = recommendedColors.length;
|
||||
var width = 30;
|
||||
var height = 30;
|
||||
var margin = 2;
|
||||
var perRow = 6;
|
||||
var picker = $("<div/>", {
|
||||
class: "red-ui-color-picker"
|
||||
}).css({
|
||||
width: ((width+margin+margin)*perRow)+"px",
|
||||
height: Math.ceil(numColors/perRow)*(height+margin+margin)+"+px"
|
||||
});
|
||||
var count = 0;
|
||||
var row = null;
|
||||
recommendedColors.forEach(function (col) {
|
||||
if ((count % perRow) == 0) {
|
||||
row = $("<div/>").appendTo(picker);
|
||||
}
|
||||
var button = $("<button/>", {
|
||||
}).css({
|
||||
width: width+"px",
|
||||
height: height+"px",
|
||||
margin: margin+"px",
|
||||
backgroundColor: col.hex,
|
||||
"border-style": "solid",
|
||||
"border-width": "1px",
|
||||
"border-color": col.luma<0.92?col.hex:'#ccc'
|
||||
}).appendTo(row);
|
||||
button.on("click", function (e) {
|
||||
e.preventDefault();
|
||||
colorPanel.hide();
|
||||
selector.val(col.hex);
|
||||
selector.trigger("change");
|
||||
});
|
||||
count++;
|
||||
});
|
||||
var colorPanel = RED.popover.panel(picker);
|
||||
colorPanel.show({
|
||||
target: colorButton
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function buildAppearanceForm(container,node) {
|
||||
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
||||
|
||||
var i,row;
|
||||
|
||||
if (node.type === "subflow") {
|
||||
var categoryRow = $("<div/>", {
|
||||
class: "form-row"
|
||||
}).appendTo(dialogForm);
|
||||
$("<label/>", {
|
||||
for: "subflow-appearance-input-category",
|
||||
"data-i18n": "editor:subflow.category"
|
||||
}).appendTo(categoryRow);
|
||||
var categorySelector = $("<select/>", {
|
||||
id: "subflow-appearance-input-category"
|
||||
}).css({
|
||||
width: "250px"
|
||||
}).appendTo(categoryRow);
|
||||
$("<input/>", {
|
||||
type: "text",
|
||||
id: "subflow-appearance-input-custom-category"
|
||||
}).css({
|
||||
display: "none",
|
||||
"margin-left": "10px",
|
||||
width: "calc(100% - 250px)"
|
||||
}).appendTo(categoryRow);
|
||||
|
||||
var categories = RED.palette.getCategories();
|
||||
categories.sort(function(A,B) {
|
||||
return A.label.localeCompare(B.label);
|
||||
})
|
||||
categories.forEach(function(cat) {
|
||||
categorySelector.append($("<option/>").val(cat.id).text(cat.label));
|
||||
})
|
||||
categorySelector.append($("<option/>").attr('disabled',true).text("---"));
|
||||
categorySelector.append($("<option/>").val("_custom_").text(RED._("palette.addCategory")));
|
||||
|
||||
$("#subflow-appearance-input-category").on("change", function() {
|
||||
var val = $(this).val();
|
||||
if (val === "_custom_") {
|
||||
$("#subflow-appearance-input-category").width(120);
|
||||
$("#subflow-appearance-input-custom-category").show();
|
||||
} else {
|
||||
$("#subflow-appearance-input-category").width(250);
|
||||
$("#subflow-appearance-input-custom-category").hide();
|
||||
}
|
||||
})
|
||||
|
||||
$("#subflow-appearance-input-category").val(node.category||"subflows");
|
||||
var userCount = 0;
|
||||
var subflowType = "subflow:"+node.id;
|
||||
|
||||
RED.nodes.eachNode(function(n) {
|
||||
if (n.type === subflowType) {
|
||||
userCount++;
|
||||
}
|
||||
});
|
||||
$("#red-ui-editor-subflow-user-count")
|
||||
.text(RED._("subflow.subflowInstances", {count:userCount})).show();
|
||||
}
|
||||
|
||||
$('<div class="form-row">'+
|
||||
'<label for="node-input-show-label-btn" data-i18n="editor.label"></label>'+
|
||||
'<button type="button" id="node-input-show-label-btn" class="red-ui-button" style="min-width: 80px; text-align: left;" type="button"><i id="node-input-show-label-btn-i" class="fa fa-toggle-on"></i> <span id="node-input-show-label-label"></span></button> '+
|
||||
'<input type="checkbox" id="node-input-show-label" style="display: none;"/>'+
|
||||
'<span style="margin-right: 2px;"/>'+
|
||||
'<input type="checkbox" id="node-input-show-label"/>'+
|
||||
'</div>').appendTo(dialogForm);
|
||||
|
||||
var setToggleState = function(state) {
|
||||
var i = $("#node-input-show-label-btn-i");
|
||||
if (!state) {
|
||||
i.addClass('fa-toggle-off');
|
||||
i.removeClass('fa-toggle-on');
|
||||
$("#node-input-show-label").prop("checked",false);
|
||||
$("#node-input-show-label-label").text(RED._("editor.hide"));
|
||||
} else {
|
||||
i.addClass('fa-toggle-on');
|
||||
i.removeClass('fa-toggle-off');
|
||||
$("#node-input-show-label").prop("checked",true);
|
||||
$("#node-input-show-label-label").text(RED._("editor.show"));
|
||||
}
|
||||
}
|
||||
dialogForm.find('#node-input-show-label-btn').on("click",function(e) {
|
||||
e.preventDefault();
|
||||
var i = $("#node-input-show-label-btn-i");
|
||||
setToggleState(i.hasClass('fa-toggle-off'));
|
||||
$("#node-input-show-label").toggleButton({
|
||||
enabledLabel: RED._("editor.show"),
|
||||
disabledLabel: RED._("editor.hide")
|
||||
})
|
||||
|
||||
if (!node.hasOwnProperty("l")) {
|
||||
// Show label if type not link
|
||||
node.l = !/^link (in|out)$/.test(node._def.type);
|
||||
}
|
||||
setToggleState(node.l);
|
||||
$("#node-input-show-label").prop("checked",node.l).trigger("change");
|
||||
|
||||
if (node.type === "subflow") {
|
||||
// subflow template can select its color
|
||||
var color = node.color ? node.color : "#DDAA99";
|
||||
var colorRow = $("<div/>", {
|
||||
class: "form-row"
|
||||
}).appendTo(dialogForm);
|
||||
$("<label/>").text(RED._("editor.color")).appendTo(colorRow);
|
||||
createColorPicker(colorRow, color);
|
||||
}
|
||||
|
||||
|
||||
// If a node has icon property in defaults, the icon of the node cannot be modified. (e.g, ui_button node in dashboard)
|
||||
if ((!node._def.defaults || !node._def.defaults.hasOwnProperty("icon"))) {
|
||||
var iconRow = $('<div class="form-row"></div>').appendTo(dialogForm);
|
||||
$('<label data-i18n="editor.settingIcon">').appendTo(iconRow);
|
||||
|
||||
var iconButton = $('<button type="button" class="red-ui-button" id="red-ui-editor-node-icon-button">').appendTo(iconRow);
|
||||
|
||||
var iconButton = $('<button type="button" class="red-ui-button red-ui-editor-node-appearance-button">').appendTo(iconRow);
|
||||
$('<i class="fa fa-caret-down"></i>').appendTo(iconButton);
|
||||
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconButton);
|
||||
var colour = RED.utils.getNodeColor(node.type, node._def);
|
||||
var icon_url = RED.utils.getNodeIcon(node._def,node);
|
||||
@@ -998,21 +1017,30 @@ RED.editor = (function() {
|
||||
iconButton.on("click", function(e) {
|
||||
e.preventDefault();
|
||||
var iconPath;
|
||||
var icon = $("#red-ui-editor-node-icon").text()||"";
|
||||
var icon = $("#red-ui-editor-node-icon").val()||"";
|
||||
if (icon) {
|
||||
iconPath = RED.utils.separateIconPath(icon);
|
||||
} else {
|
||||
iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||
}
|
||||
showIconPicker(iconRow,node,iconPath,function(newIcon) {
|
||||
$("#red-ui-editor-node-icon").text(newIcon||"");
|
||||
var backgroundColor = RED.utils.getNodeColor(node.type, node._def);
|
||||
if (node.type === "subflow") {
|
||||
backgroundColor = $("#red-ui-editor-node-color").val();
|
||||
}
|
||||
showIconPicker(iconButton,backgroundColor,iconPath,false,function(newIcon) {
|
||||
$("#red-ui-editor-node-icon").val(newIcon||"");
|
||||
var icon_url = RED.utils.getNodeIcon(node._def,{type:node.type,icon:newIcon});
|
||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||
});
|
||||
});
|
||||
$('<div id="red-ui-editor-node-icon">').text(node.icon).appendTo(iconButton);
|
||||
|
||||
RED.popover.tooltip(iconButton, function() {
|
||||
return $("#red-ui-editor-node-icon").val() || RED._("editor.default");
|
||||
})
|
||||
$('<input type="hidden" id="red-ui-editor-node-icon">').val(node.icon).appendTo(iconRow);
|
||||
}
|
||||
|
||||
|
||||
$('<div class="form-row"><span data-i18n="editor.portLabels"></span></div>').appendTo(dialogForm);
|
||||
|
||||
var inputCount = node.inputs || node._def.inputs || 0;
|
||||
@@ -1048,6 +1076,7 @@ RED.editor = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateLabels(editing_node, changes, outputMap) {
|
||||
var inputLabels = $("#red-ui-editor-node-label-form-inputs").children().find("input");
|
||||
var outputLabels = $("#red-ui-editor-node-label-form-outputs").children().find("input");
|
||||
@@ -1291,11 +1320,13 @@ RED.editor = (function() {
|
||||
newValue = parseInt(newValue);
|
||||
}
|
||||
}
|
||||
if (editing_node._def.defaults[d].type) {
|
||||
if (newValue == "_ADD_") {
|
||||
newValue = "";
|
||||
}
|
||||
}
|
||||
if (editing_node[d] != newValue) {
|
||||
if (editing_node._def.defaults[d].type) {
|
||||
if (newValue == "_ADD_") {
|
||||
newValue = "";
|
||||
}
|
||||
// Change to a related config node
|
||||
var configNode = RED.nodes.node(editing_node[d]);
|
||||
if (configNode) {
|
||||
@@ -1335,7 +1366,7 @@ RED.editor = (function() {
|
||||
}
|
||||
|
||||
if (!editing_node._def.defaults || !editing_node._def.defaults.hasOwnProperty("icon")) {
|
||||
var icon = $("#red-ui-editor-node-icon").text()||""
|
||||
var icon = $("#red-ui-editor-node-icon").val()||""
|
||||
if (!isDefaultIcon) {
|
||||
if (icon !== editing_node.icon) {
|
||||
changes.icon = editing_node.icon;
|
||||
@@ -1393,6 +1424,20 @@ RED.editor = (function() {
|
||||
node.l = true;
|
||||
}
|
||||
}
|
||||
if ($("#node-input-node-disabled").prop('checked')) {
|
||||
if (node.d !== true) {
|
||||
changes.d = node.d;
|
||||
changed = true;
|
||||
node.d = true;
|
||||
}
|
||||
} else {
|
||||
if (node.d === true) {
|
||||
changes.d = node.d;
|
||||
changed = true;
|
||||
delete node.d;
|
||||
}
|
||||
}
|
||||
|
||||
node.resize = true;
|
||||
|
||||
var oldInfo = node.info;
|
||||
@@ -1424,13 +1469,13 @@ RED.editor = (function() {
|
||||
|
||||
if (type === "subflow") {
|
||||
var old_env = editing_node.env;
|
||||
var new_env = exportEnvList($("#node-input-env-container").editableList("items"));
|
||||
if (!isSameEnv(old_env, new_env)) {
|
||||
var new_env = RED.subflow.exportSubflowInstanceEnv(editing_node);
|
||||
if (!isSameObj(old_env, new_env)) {
|
||||
editing_node.env = new_env;
|
||||
changes.env = editing_node.env;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
var wasChanged = editing_node.changed;
|
||||
@@ -1495,6 +1540,14 @@ RED.editor = (function() {
|
||||
var trayBody = tray.find('.red-ui-tray-body');
|
||||
trayBody.parent().css('overflow','hidden');
|
||||
|
||||
var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter)
|
||||
|
||||
$('<input id="node-input-node-disabled" type="checkbox">').prop("checked",!!node.d).appendTo(trayFooterLeft).toggleButton({
|
||||
enabledIcon: "fa-circle-thin",
|
||||
disabledIcon: "fa-ban",
|
||||
invertState: true
|
||||
})
|
||||
|
||||
var editorTabEl = $('<ul></ul>').appendTo(trayBody);
|
||||
var editorContent = $('<div></div>').appendTo(trayBody);
|
||||
|
||||
@@ -1540,6 +1593,19 @@ RED.editor = (function() {
|
||||
buildEditForm(nodePropertiesTab.content,"dialog-form",type,ns,node);
|
||||
editorTabs.addTab(nodePropertiesTab);
|
||||
|
||||
if (/^subflow:/.test(node.type)) {
|
||||
var subflowPropertiesTab = {
|
||||
id: "editor-subflow-envProperties",
|
||||
label: RED._("editor-tab.envProperties"),
|
||||
name: RED._("editor-tab.envProperties"),
|
||||
content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
||||
iconClass: "fa fa-list"
|
||||
};
|
||||
|
||||
RED.subflow.buildPropertiesForm(subflowPropertiesTab.content,node);
|
||||
editorTabs.addTab(subflowPropertiesTab);
|
||||
}
|
||||
|
||||
if (!node._def.defaults || !node._def.defaults.hasOwnProperty('info')) {
|
||||
var descriptionTab = {
|
||||
id: "editor-tab-description",
|
||||
@@ -1672,9 +1738,17 @@ RED.editor = (function() {
|
||||
var trayHeader = tray.find(".red-ui-tray-header");
|
||||
var trayBody = tray.find('.red-ui-tray-body');
|
||||
var trayFooter = tray.find(".red-ui-tray-footer");
|
||||
var userCountDiv;
|
||||
|
||||
var trayFooterLeft = $('<div class="red-ui-tray-footer-left"></div>').appendTo(trayFooter)
|
||||
|
||||
$('<input id="node-config-input-node-disabled" type="checkbox">').prop("checked",!!editing_config_node.d).appendTo(trayFooterLeft).toggleButton({
|
||||
enabledIcon: "fa-circle-thin",
|
||||
disabledIcon: "fa-ban",
|
||||
invertState: true
|
||||
})
|
||||
|
||||
if (node_def.hasUsers !== false) {
|
||||
userCountDiv = $('<div class="red-ui-tray-footer-left"><i class="fa fa-info-circle"></i> <span></span></div>').prependTo(trayFooter);
|
||||
$('<span><i class="fa fa-info-circle"></i> <span id="red-ui-editor-config-user-count"></span></span>').css("margin-left", "10px").appendTo(trayFooterLeft);
|
||||
}
|
||||
trayFooter.append('<span class="red-ui-tray-footer-right"><span id="red-ui-editor-config-scope-warning" data-i18n="[title]editor.errors.scopeChange"><i class="fa fa-warning"></i></span><select id="red-ui-editor-config-scope"></select></span>');
|
||||
|
||||
@@ -1693,7 +1767,8 @@ RED.editor = (function() {
|
||||
RED.tray.resize();
|
||||
}
|
||||
},
|
||||
collapsible: true
|
||||
collapsible: true,
|
||||
menu: false
|
||||
});
|
||||
|
||||
var nodePropertiesTab = {
|
||||
@@ -1768,8 +1843,8 @@ RED.editor = (function() {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (node_def.hasUsers !== false && userCountDiv) {
|
||||
userCountDiv.find("span").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
|
||||
if (node_def.hasUsers !== false) {
|
||||
$("#red-ui-editor-config-user-count").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
|
||||
}
|
||||
trayBody.i18n();
|
||||
trayFooter.i18n();
|
||||
@@ -1800,7 +1875,6 @@ RED.editor = (function() {
|
||||
var configId = editing_config_node.id;
|
||||
var configAdding = adding;
|
||||
var configTypeDef = RED.nodes.getType(configType);
|
||||
|
||||
if (configTypeDef.oneditcancel) {
|
||||
// TODO: what to pass as this to call
|
||||
if (configTypeDef.oneditcancel) {
|
||||
@@ -1904,6 +1978,16 @@ RED.editor = (function() {
|
||||
editing_config_node.label = configTypeDef.label;
|
||||
editing_config_node.z = scope;
|
||||
|
||||
if ($("#node-config-input-node-disabled").prop('checked')) {
|
||||
if (editing_config_node.d !== true) {
|
||||
editing_config_node.d = true;
|
||||
}
|
||||
} else {
|
||||
if (editing_config_node.d === true) {
|
||||
delete editing_config_node.d;
|
||||
}
|
||||
}
|
||||
|
||||
if (scope) {
|
||||
// Search for nodes that use this one that are no longer
|
||||
// in scope, so must be removed
|
||||
@@ -2058,7 +2142,7 @@ RED.editor = (function() {
|
||||
RED.nodes.eachConfig(function(config) {
|
||||
if (config.type == type && (!config.z || config.z === activeWorkspace.id)) {
|
||||
var label = RED.utils.getNodeLabel(config,config.id);
|
||||
config.__label__ = label;
|
||||
config.__label__ = label+(config.d?" ["+RED._("workspace.disabled")+"]":"");
|
||||
configNodes.push(config);
|
||||
}
|
||||
});
|
||||
@@ -2127,16 +2211,16 @@ RED.editor = (function() {
|
||||
if (updateLabels(editing_node, changes, null)) {
|
||||
changed = true;
|
||||
}
|
||||
var icon = $("#red-ui-editor-node-icon").text()||"";
|
||||
if ((editing_node.icon === undefined && icon !== "node-red/subflow.png") ||
|
||||
var icon = $("#red-ui-editor-node-icon").val()||"";
|
||||
if ((editing_node.icon === undefined && icon !== "node-red/subflow.svg") ||
|
||||
(editing_node.icon !== undefined && editing_node.icon !== icon)) {
|
||||
changes.icon = editing_node.icon;
|
||||
editing_node.icon = icon;
|
||||
changed = true;
|
||||
}
|
||||
var newCategory = $("#subflow-input-category").val().trim();
|
||||
var newCategory = $("#subflow-appearance-input-category").val().trim();
|
||||
if (newCategory === "_custom_") {
|
||||
newCategory = $("#subflow-input-custom-category").val().trim();
|
||||
newCategory = $("#subflow-appearance-input-custom-category").val().trim();
|
||||
if (newCategory === "") {
|
||||
newCategory = editing_node.category;
|
||||
}
|
||||
@@ -2150,14 +2234,28 @@ RED.editor = (function() {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
var oldColor = editing_node.color;
|
||||
var newColor = $("#red-ui-editor-node-color").val();
|
||||
if (oldColor !== newColor) {
|
||||
editing_node.color = newColor;
|
||||
changes.color = newColor;
|
||||
changed = true;
|
||||
RED.utils.clearNodeColorCache();
|
||||
if (editing_node.type === "subflow") {
|
||||
var nodeDefinition = RED.nodes.getType(
|
||||
"subflow:" + editing_node.id
|
||||
);
|
||||
nodeDefinition["color"] = newColor;
|
||||
}
|
||||
}
|
||||
|
||||
var old_env = editing_node.env;
|
||||
var new_env = exportEnvList($("#node-input-env-container").editableList("items"));
|
||||
if (!isSameEnv(old_env, new_env)) {
|
||||
var new_env = RED.subflow.exportSubflowTemplateEnv($("#node-input-env-container").editableList("items"));
|
||||
if (!isSameObj(old_env, new_env)) {
|
||||
editing_node.env = new_env;
|
||||
changes.env = editing_node.env;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
RED.palette.refresh();
|
||||
|
||||
if (changed) {
|
||||
@@ -2171,6 +2269,7 @@ RED.editor = (function() {
|
||||
id:n.id,
|
||||
changed:n.changed
|
||||
})
|
||||
n._def.color = editing_node.color;
|
||||
n.changed = true;
|
||||
n.dirty = true;
|
||||
updateNodeProperties(n);
|
||||
@@ -2198,21 +2297,39 @@ RED.editor = (function() {
|
||||
],
|
||||
resize: function(size) {
|
||||
$(".red-ui-tray-content").height(size.height - 50);
|
||||
// var form = $(".red-ui-tray-content form").height(size.height - 50 - 40);
|
||||
var rows = $("#dialog-form>div:not(.node-input-env-container-row)");
|
||||
var height = size.height;
|
||||
for (var i=0; i<rows.size(); i++) {
|
||||
height -= $(rows[i]).outerHeight(true);
|
||||
var envContainer = $("#node-input-env-container");
|
||||
if (envContainer.length) {
|
||||
// var form = $(".red-ui-tray-content form").height(size.height - 50 - 40);
|
||||
var rows = $("#dialog-form>div:not(#subflow-env-tabs-content)");
|
||||
var height = size.height;
|
||||
for (var i=0; i<rows.size(); i++) {
|
||||
height -= $(rows[i]).outerHeight(true);
|
||||
}
|
||||
// var editorRow = $("#dialog-form>div.node-input-env-container-row");
|
||||
// height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
|
||||
$("#node-input-env-container").editableList('height',height-95);
|
||||
}
|
||||
var editorRow = $("#dialog-form>div.node-input-env-container-row");
|
||||
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
|
||||
$("#node-input-env-container").editableList('height',height-80);
|
||||
},
|
||||
open: function(tray) {
|
||||
var trayFooter = tray.find(".red-ui-tray-footer");
|
||||
var trayFooterLeft = $("<div/>", {
|
||||
class: "red-ui-tray-footer-left"
|
||||
}).appendTo(trayFooter)
|
||||
var trayBody = tray.find('.red-ui-tray-body');
|
||||
trayBody.parent().css('overflow','hidden');
|
||||
|
||||
if (editing_node.type === "subflow") {
|
||||
var span = $("<span/>").css({
|
||||
"margin-left": "10px"
|
||||
}).appendTo(trayFooterLeft);
|
||||
$("<i/>", {
|
||||
class: "fa fa-info-circle"
|
||||
}).appendTo(span);
|
||||
$("<span/>").text(" ").appendTo(span);
|
||||
$("<i/>", {
|
||||
id: "red-ui-editor-subflow-user-count"
|
||||
}).appendTo(span);
|
||||
}
|
||||
|
||||
if (editing_node) {
|
||||
RED.sidebar.info.refresh(editing_node);
|
||||
@@ -2233,7 +2350,8 @@ RED.editor = (function() {
|
||||
RED.tray.resize();
|
||||
}
|
||||
},
|
||||
collapsible: true
|
||||
collapsible: true,
|
||||
menu: false
|
||||
});
|
||||
|
||||
var nodePropertiesTab = {
|
||||
@@ -2272,46 +2390,9 @@ RED.editor = (function() {
|
||||
buildAppearanceForm(appearanceTab.content,editing_node);
|
||||
editorTabs.addTab(appearanceTab);
|
||||
|
||||
|
||||
|
||||
|
||||
$("#subflow-input-name").val(subflow.name);
|
||||
RED.text.bidi.prepareInput($("#subflow-input-name"));
|
||||
|
||||
$("#subflow-input-category").empty();
|
||||
var categories = RED.palette.getCategories();
|
||||
categories.sort(function(A,B) {
|
||||
return A.label.localeCompare(B.label);
|
||||
})
|
||||
categories.forEach(function(cat) {
|
||||
$("#subflow-input-category").append($("<option></option>").val(cat.id).text(cat.label));
|
||||
})
|
||||
$("#subflow-input-category").append($("<option></option>").attr('disabled',true).text("---"));
|
||||
$("#subflow-input-category").append($("<option></option>").val("_custom_").text(RED._("palette.addCategory")));
|
||||
|
||||
|
||||
$("#subflow-input-category").on("change", function() {
|
||||
var val = $(this).val();
|
||||
if (val === "_custom_") {
|
||||
$("#subflow-input-category").width(120);
|
||||
$("#subflow-input-custom-category").show();
|
||||
} else {
|
||||
$("#subflow-input-category").width(250);
|
||||
$("#subflow-input-custom-category").hide();
|
||||
}
|
||||
})
|
||||
|
||||
$("#subflow-input-category").val(subflow.category||"subflows");
|
||||
var userCount = 0;
|
||||
var subflowType = "subflow:"+editing_node.id;
|
||||
|
||||
RED.nodes.eachNode(function(n) {
|
||||
if (n.type === subflowType) {
|
||||
userCount++;
|
||||
}
|
||||
});
|
||||
$("#subflow-dialog-user-count").text(RED._("subflow.subflowInstances", {count:userCount})).show();
|
||||
|
||||
trayBody.i18n();
|
||||
finishedBuilding = true;
|
||||
},
|
||||
@@ -2405,7 +2486,7 @@ RED.editor = (function() {
|
||||
editor.toolbar = customEditTypes['_markdown'].buildToolbar(toolbarRow,editor);
|
||||
if (options.expandable !== false) {
|
||||
var expandButton = $('<button type="button" class="red-ui-button" style="float: right;"><i class="fa fa-expand"></i></button>').appendTo(editor.toolbar);
|
||||
|
||||
RED.popover.tooltip(expandButton, RED._("markdownEditor.expand"));
|
||||
expandButton.on("click", function(e) {
|
||||
e.preventDefault();
|
||||
var value = editor.getValue();
|
||||
@@ -2432,6 +2513,7 @@ RED.editor = (function() {
|
||||
content: RED._("markdownEditor.format"),
|
||||
autoClose: 50
|
||||
});
|
||||
session.setUseWrapMode(true);
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
@@ -2464,6 +2546,8 @@ RED.editor = (function() {
|
||||
validateNode: validateNode,
|
||||
updateNodeProperties: updateNodeProperties, // TODO: only exposed for edit-undo
|
||||
|
||||
showIconPicker:showIconPicker,
|
||||
|
||||
/**
|
||||
* Show a type editor.
|
||||
* @param {string} type - the type to display
|
||||
@@ -2476,7 +2560,7 @@ RED.editor = (function() {
|
||||
/**
|
||||
* Register a type editor.
|
||||
* @param {string} type - the type name
|
||||
* @param {object} options - the editor definition
|
||||
* @param {object} definition - the editor definition
|
||||
* @function
|
||||
* @memberof RED.editor
|
||||
*/
|
||||
|
@@ -207,6 +207,7 @@
|
||||
}
|
||||
expressionEditor.getSession().setValue(v||"",-1);
|
||||
});
|
||||
funcSelect.change();
|
||||
|
||||
var tabs = RED.tabs.create({
|
||||
element: $("#red-ui-editor-type-expression-tabs"),
|
||||
|
@@ -16,7 +16,420 @@
|
||||
(function() {
|
||||
|
||||
|
||||
var template = '<script type="text/x-red" data-template-name="_json"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><button id="node-input-json-reformat" class="red-ui-button red-ui-button-small"><span data-i18n="jsonEditor.format"></span></button></div><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div></div></script>';
|
||||
// var template = '<script type="text/x-red" data-template-name="_json"></script>';
|
||||
var template = '<script type="text/x-red" data-template-name="_json">'+
|
||||
'<ul id="red-ui-editor-type-json-tabs"></ul>'+
|
||||
'<div id="red-ui-editor-type-json-tab-raw" class="red-ui-editor-type-json-tab-content hide">'+
|
||||
'<div class="form-row" style="margin-bottom: 3px; text-align: right;">'+
|
||||
'<button id="node-input-json-reformat" class="red-ui-button red-ui-button-small"><span data-i18n="jsonEditor.format"></span></button>'+
|
||||
'</div>'+
|
||||
'<div class="form-row node-text-editor-row">'+
|
||||
'<div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div>'+
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'<div id="red-ui-editor-type-json-tab-ui" class="red-ui-editor-type-json-tab-content hide">'+
|
||||
'<div id="red-ui-editor-type-json-tab-ui-container"></div>'+
|
||||
'</div>'+
|
||||
'</script>';
|
||||
|
||||
var activeTab;
|
||||
|
||||
function insertNewItem(parent,index,copyIndex) {
|
||||
var newValue = "";
|
||||
|
||||
if (parent.children.length > 0) {
|
||||
switch (parent.children[Math.max(0,Math.min(parent.children.length-1,copyIndex))].type) {
|
||||
case 'string': newValue = ""; break;
|
||||
case 'number': newValue = 0; break;
|
||||
case 'boolean': newValue = true; break;
|
||||
case 'null': newValue = null; break;
|
||||
case 'object': newValue = {}; break;
|
||||
case 'array': newValue = []; break;
|
||||
}
|
||||
}
|
||||
var newKey;
|
||||
if (parent.type === 'array') {
|
||||
newKey = parent.children.length;
|
||||
} else {
|
||||
var usedKeys = {};
|
||||
parent.children.forEach(function(child) { usedKeys[child.key] = true })
|
||||
var keyRoot = "item";
|
||||
var keySuffix = 2;
|
||||
newKey = keyRoot;
|
||||
while(usedKeys[newKey]) {
|
||||
newKey = keyRoot+"-"+(keySuffix++);
|
||||
}
|
||||
}
|
||||
var newItem = handleItem(newKey,newValue,parent.depth+1,parent);
|
||||
parent.treeList.insertChildAt(newItem, index, true);
|
||||
parent.treeList.expand();
|
||||
}
|
||||
function showObjectMenu(button,item) {
|
||||
var elementPos = button.offset();
|
||||
var options = [];
|
||||
if (item.parent) {
|
||||
options.push({id:"red-ui-editor-type-json-menu-insert-above", icon:"fa fa-toggle-up", label:RED._('jsonEditor.insertAbove'),onselect:function(){
|
||||
var index = item.parent.children.indexOf(item);
|
||||
insertNewItem(item.parent,index,index);
|
||||
}});
|
||||
options.push({id:"red-ui-editor-type-json-menu-insert-below", icon:"fa fa-toggle-down", label:RED._('jsonEditor.insertBelow'),onselect:function(){
|
||||
var index = item.parent.children.indexOf(item)+1;
|
||||
insertNewItem(item.parent,index,index-1);
|
||||
}});
|
||||
}
|
||||
if (item.type === 'array' || item.type === 'object') {
|
||||
options.push({id:"red-ui-editor-type-json-menu-add-child", icon:"fa fa-plus", label:RED._('jsonEditor.addItem'),onselect:function(){
|
||||
insertNewItem(item,item.children.length,item.children.length-1);
|
||||
}});
|
||||
}
|
||||
if (item.parent) {
|
||||
options.push({id:"red-ui-editor-type-json-menu-copy-path", icon:"fa fa-terminal", label:RED._('jsonEditor.copyPath'),onselect:function(){
|
||||
var i = item;
|
||||
var path = "";
|
||||
var newPath;
|
||||
while(i.parent) {
|
||||
if (i.parent.type === "array") {
|
||||
newPath = "["+i.key+"]";
|
||||
} else {
|
||||
if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(i.key)) {
|
||||
newPath = i.key;
|
||||
} else {
|
||||
newPath = "[\""+i.key.replace(/"/,"\\\"")+"\"]"
|
||||
}
|
||||
}
|
||||
path = newPath+(path.length>0 && path[0] !== "["?".":"")+path;
|
||||
i = i.parent;
|
||||
}
|
||||
RED.clipboard.copyText(path,item.element,"clipboard.copyMessagePath");
|
||||
}});
|
||||
|
||||
options.push({id:"red-ui-editor-type-json-menu-duplicate", icon:"fa fa-copy", label:RED._("jsonEditor.duplicate"),onselect:function(){
|
||||
var newKey = item.key;
|
||||
if (item.parent.type === 'array') {
|
||||
newKey = parent.children.length;
|
||||
} else {
|
||||
var m = /^(.*?)(-(\d+))?$/.exec(newKey);
|
||||
var usedKeys = {};
|
||||
item.parent.children.forEach(function(child) { usedKeys[child.key] = true })
|
||||
var keyRoot = m[1];
|
||||
var keySuffix = 2;
|
||||
if (m[3] !== undefined) {
|
||||
keySuffix = parseInt(m[3]);
|
||||
}
|
||||
newKey = keyRoot;
|
||||
while(usedKeys[newKey]) {
|
||||
newKey = keyRoot+"-"+(keySuffix++);
|
||||
}
|
||||
}
|
||||
var newItem = handleItem(newKey,convertToObject(item),item.parent.depth+1,item.parent);
|
||||
var index = item.parent.children.indexOf(item)+1;
|
||||
|
||||
item.parent.treeList.insertChildAt(newItem, index, true);
|
||||
item.parent.treeList.expand();
|
||||
}});
|
||||
|
||||
options.push({id:"red-ui-editor-type-json-menu-delete", icon:"fa fa-times", label:RED._('common.label.delete'),onselect:function(){
|
||||
item.treeList.remove();
|
||||
}});
|
||||
}
|
||||
if (item.type === 'array' || item.type === 'object') {
|
||||
options.push(null)
|
||||
options.push({id:"red-ui-editor-type-json-menu-expand-children",icon:"fa fa-angle-double-down", label:RED._('jsonEditor.expandItems'),onselect:function(){
|
||||
item.treeList.expand();
|
||||
item.children.forEach(function(child) {
|
||||
child.treeList.expand();
|
||||
})
|
||||
}});
|
||||
options.push({id:"red-ui-editor-type-json-menu-collapse-children",icon:"fa fa-angle-double-up", label:RED._('jsonEditor.collapseItems'),onselect:function(){
|
||||
item.treeList.collapse();
|
||||
item.children.forEach(function(child) {
|
||||
child.treeList.collapse();
|
||||
})
|
||||
}});
|
||||
}
|
||||
|
||||
var menuOptionMenu = RED.menu.init({
|
||||
id:"red-ui-editor-type-json-menu",
|
||||
options: options
|
||||
});
|
||||
menuOptionMenu.css({
|
||||
position: "absolute"
|
||||
})
|
||||
menuOptionMenu.on('mouseleave', function(){ $(this).hide() });
|
||||
menuOptionMenu.on('mouseup', function() { $(this).hide() });
|
||||
menuOptionMenu.appendTo("body");
|
||||
var top = elementPos.top;
|
||||
var height = menuOptionMenu.height();
|
||||
var winHeight = $(window).height();
|
||||
if (top+height > winHeight) {
|
||||
top -= (top+height)-winHeight + 20;
|
||||
}
|
||||
menuOptionMenu.css({
|
||||
top: top+"px",
|
||||
left: elementPos.left+"px"
|
||||
})
|
||||
menuOptionMenu.show();
|
||||
}
|
||||
|
||||
function parseObject(obj,depth,parent) {
|
||||
var result = [];
|
||||
for (var prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
result.push(handleItem(prop,obj[prop],depth,parent));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function parseArray(obj,depth,parent) {
|
||||
var result = [];
|
||||
var l = obj.length;
|
||||
for (var i=0;i<l;i++) {
|
||||
result.push(handleItem(i,obj[i],depth,parent));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function handleItem(key,val,depth,parent) {
|
||||
var item = {depth:depth, type: typeof val};
|
||||
var container = $('<span class="red-ui-editor-type-json-editor-label">');
|
||||
if (key != null) {
|
||||
item.key = key;
|
||||
var keyText;
|
||||
if (typeof key === 'string') {
|
||||
keyText = '"'+key+'"';
|
||||
} else {
|
||||
keyText = key;
|
||||
}
|
||||
var keyLabel = $('<span class="red-ui-debug-msg-object-key red-ui-editor-type-json-editor-label-key">').text(keyText).appendTo(container);
|
||||
keyLabel.addClass('red-ui-debug-msg-type-'+(typeof key));
|
||||
if (parent && parent.type === "array") {
|
||||
keyLabel.addClass("red-ui-editor-type-json-editor-label-array-key")
|
||||
}
|
||||
|
||||
keyLabel.on("click", function(evt) {
|
||||
if (item.parent.type === 'array') {
|
||||
return;
|
||||
}
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
var w = Math.max(150,keyLabel.width());
|
||||
var keyInput = $('<input type="text" class="red-ui-editor-type-json-editor-key">').css({width:w+"px"}).val(""+item.key).insertAfter(keyLabel).typedInput({types:['str']});
|
||||
$(document).on("mousedown.nr-ui-json-editor", function(evt) {
|
||||
var typedInputElement = keyInput.next(".red-ui-typedInput-container")[0];
|
||||
var target = evt.target;
|
||||
while (target.nodeName !== 'BODY' && target !== typedInputElement && !$(target).hasClass("red-ui-typedInput-options")) {
|
||||
target = target.parentElement;
|
||||
}
|
||||
if (target.nodeName === 'BODY') {
|
||||
var newKey = keyInput.typedInput("value");
|
||||
item.key = newKey;
|
||||
var keyText;
|
||||
if (typeof newKey === 'string') {
|
||||
keyText = '"'+newKey+'"';
|
||||
} else {
|
||||
keyText = newKey;
|
||||
}
|
||||
keyLabel.text(keyText);
|
||||
keyInput.remove();
|
||||
keyLabel.show();
|
||||
$(document).off("mousedown.nr-ui-json-editor");
|
||||
$(document).off("keydown.nr-ui-json-editor");
|
||||
}
|
||||
});
|
||||
$(document).on("keydown.nr-ui-json-editor",function(evt) {
|
||||
if (evt.keyCode === 27) {
|
||||
// Escape
|
||||
keyInput.remove();
|
||||
keyLabel.show();
|
||||
$(document).off("mousedown.nr-ui-json-editor");
|
||||
$(document).off("keydown.nr-ui-json-editor");
|
||||
}
|
||||
});
|
||||
keyLabel.hide();
|
||||
});
|
||||
$('<span>').text(" : ").appendTo(container);
|
||||
}
|
||||
|
||||
if (Array.isArray(val)) {
|
||||
item.expanded = depth < 2;
|
||||
item.type = "array";
|
||||
item.deferBuild = depth >= 2;
|
||||
item.children = parseArray(val,depth+1,item);
|
||||
} else if (val !== null && item.type === "object") {
|
||||
item.expanded = depth < 2;
|
||||
item.children = parseObject(val,depth+1,item);
|
||||
item.deferBuild = depth >= 2;
|
||||
} else {
|
||||
item.value = val;
|
||||
if (val === null) {
|
||||
item.type = 'null'
|
||||
}
|
||||
}
|
||||
|
||||
var valType;
|
||||
var valValue = "";
|
||||
var valClass;
|
||||
switch(item.type) {
|
||||
case 'string': valType = 'str'; valValue = '"'+item.value+'"'; valClass = "red-ui-debug-msg-type-string"; break;
|
||||
case 'number': valType = 'num'; valValue = item.value; valClass = "red-ui-debug-msg-type-number";break;
|
||||
case 'boolean': valType = 'bool'; valValue = item.value; valClass = "red-ui-debug-msg-type-other";break;
|
||||
case 'null': valType = item.type; valValue = item.type; valClass = "red-ui-debug-msg-type-null";break;
|
||||
case 'object':
|
||||
valType = item.type;
|
||||
valValue = item.type;//+"{"+item.children.length+"}";
|
||||
valClass = "red-ui-debug-msg-type-meta";
|
||||
break;
|
||||
case 'array':
|
||||
valType = item.type;
|
||||
valValue = item.type+"["+item.children.length+"]";
|
||||
valClass = "red-ui-debug-msg-type-meta";
|
||||
break;
|
||||
}
|
||||
//
|
||||
var orphanedChildren;
|
||||
var valueLabel = $('<span class="red-ui-editor-type-json-editor-label-value">').addClass(valClass).text(valValue).appendTo(container);
|
||||
valueLabel.on("click", function(evt) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
if (valType === 'str') {
|
||||
valValue = valValue.substring(1,valValue.length-1);
|
||||
} else if (valType === 'array') {
|
||||
valValue = "";
|
||||
} else if (valType === 'object') {
|
||||
valValue = "";
|
||||
}
|
||||
var w = Math.max(150,valueLabel.width());
|
||||
var val = $('<input type="text" class="red-ui-editor-type-json-editor-value">').css({width:w+"px"}).val(""+valValue).insertAfter(valueLabel).typedInput({
|
||||
types:[
|
||||
'str','num','bool',
|
||||
{value:"null",label:RED._("common.type.null"),hasValue:false},
|
||||
{value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.png"},
|
||||
{value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.png"}
|
||||
],
|
||||
default: valType
|
||||
});
|
||||
$(document).on("mousedown.nr-ui-json-editor", function(evt) {
|
||||
var typedInputElement = val.next(".red-ui-typedInput-container")[0];
|
||||
var target = evt.target;
|
||||
while (target.nodeName !== 'BODY' && target !== typedInputElement && !$(target).hasClass("red-ui-typedInput-options")) {
|
||||
target = target.parentElement;
|
||||
}
|
||||
if (target.nodeName === 'BODY') {
|
||||
valType = val.typedInput("type");
|
||||
valValue = val.typedInput("value");
|
||||
if (valType === 'num') {
|
||||
valValue = valValue.trim();
|
||||
if (isNaN(valValue)) {
|
||||
valType = 'str';
|
||||
} else if (valValue === "") {
|
||||
valValue = 0;
|
||||
}
|
||||
}
|
||||
item.value = valValue;
|
||||
var valClass;
|
||||
switch(valType) {
|
||||
case 'str': if (item.children) { orphanedChildren = item.children } item.treeList.makeLeaf(true); item.type = "string"; valClass = "red-ui-debug-msg-type-string"; valValue = '"'+valValue+'"'; break;
|
||||
case 'num': if (item.children) { orphanedChildren = item.children } item.treeList.makeLeaf(true); item.type = "number"; valClass = "red-ui-debug-msg-type-number"; break;
|
||||
case 'bool': if (item.children) { orphanedChildren = item.children } item.treeList.makeLeaf(true); item.type = "boolean"; valClass = "red-ui-debug-msg-type-other"; item.value = (valValue === "true"); break;
|
||||
case 'null': if (item.children) { orphanedChildren = item.children } item.treeList.makeLeaf(true); item.type = "null"; valClass = "red-ui-debug-msg-type-null"; item.value = valValue = "null"; break;
|
||||
case 'object':
|
||||
item.treeList.makeParent(orphanedChildren);
|
||||
item.type = "object";
|
||||
valClass = "red-ui-debug-msg-type-meta";
|
||||
item.value = valValue = "object";
|
||||
item.children.forEach(function(child,i) {
|
||||
if (child.hasOwnProperty('_key')) {
|
||||
child.key = child._key;
|
||||
delete child._key;
|
||||
var keyText;
|
||||
var keyLabel = child.element.find(".red-ui-editor-type-json-editor-label-key");
|
||||
keyLabel.removeClass("red-ui-editor-type-json-editor-label-array-key");
|
||||
if (typeof child.key === 'string') {
|
||||
keyText = '"'+child.key+'"';
|
||||
keyLabel.addClass('red-ui-debug-msg-type-string');
|
||||
keyLabel.removeClass('red-ui-debug-msg-type-number');
|
||||
} else {
|
||||
keyText = child.key;
|
||||
keyLabel.removeClass('red-ui-debug-msg-type-string');
|
||||
keyLabel.addClass('red-ui-debug-msg-type-number');
|
||||
}
|
||||
keyLabel.text(keyText);
|
||||
}
|
||||
})
|
||||
break;
|
||||
case 'array':
|
||||
item.treeList.makeParent(orphanedChildren);
|
||||
item.type = "array";
|
||||
valClass = "red-ui-debug-msg-type-meta";
|
||||
item.value = valValue = "array["+(item.children.length)+"]";
|
||||
item.children.forEach(function(child,i) {
|
||||
child._key = child.key;
|
||||
child.key = i;
|
||||
child.element.find(".red-ui-editor-type-json-editor-label-key")
|
||||
.addClass("red-ui-editor-type-json-editor-label-array-key")
|
||||
.text(""+child.key)
|
||||
.removeClass('red-ui-debug-msg-type-string')
|
||||
.addClass('red-ui-debug-msg-type-number');
|
||||
})
|
||||
break;
|
||||
}
|
||||
valueLabel.text(valValue).removeClass().addClass("red-ui-editor-type-json-editor-label-value "+valClass);
|
||||
val.remove();
|
||||
valueLabel.show();
|
||||
$(document).off("mousedown.nr-ui-json-editor");
|
||||
$(document).off("keydown.nr-ui-json-editor");
|
||||
}
|
||||
})
|
||||
|
||||
$(document).on("keydown.nr-ui-json-editor",function(evt) {
|
||||
if (evt.keyCode === 27) {
|
||||
// Escape
|
||||
val.remove();
|
||||
valueLabel.show();
|
||||
if (valType === 'str') {
|
||||
valValue = '"'+valValue+'"';
|
||||
}
|
||||
$(document).off("mousedown.nr-ui-json-editor");
|
||||
$(document).off("keydown.nr-ui-json-editor");
|
||||
}
|
||||
});
|
||||
valueLabel.hide();
|
||||
})
|
||||
item.gutter = $('<span class="red-ui-editor-type-json-editor-item-gutter"></span>');
|
||||
|
||||
if (parent) {//red-ui-editor-type-json-editor-item-handle
|
||||
$('<span class="red-ui-editor-type-json-editor-item-handle"><i class="fa fa-bars"></span>').appendTo(item.gutter);
|
||||
} else {
|
||||
$('<span></span>').appendTo(item.gutter);
|
||||
}
|
||||
$('<button type="button" class="editor-button editor-button-small"><i class="fa fa-caret-down"></button>').appendTo(item.gutter).on("click", function(evt) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
showObjectMenu($(this), item);
|
||||
});
|
||||
item.element = container;
|
||||
return item;
|
||||
}
|
||||
function convertToObject(item) {
|
||||
var element;
|
||||
switch (item.type) {
|
||||
case 'string': element = item.value; break;
|
||||
case 'number': element = Number(item.value); break;
|
||||
case 'boolean': element = item.value; break;
|
||||
case 'null': element = null; break;
|
||||
case 'object':
|
||||
element = {};
|
||||
item.children.forEach(function(child) {
|
||||
element[child.key] = convertToObject(child);
|
||||
})
|
||||
break;
|
||||
case 'array':
|
||||
element = item.children.map(function(child) {
|
||||
return convertToObject(child);
|
||||
})
|
||||
break;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
var definition = {
|
||||
show: function(options) {
|
||||
@@ -41,9 +454,11 @@
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var rootNode;
|
||||
|
||||
var trayOptions = {
|
||||
title: options.title,
|
||||
width: "inherit",
|
||||
width: options.width||700,
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
@@ -60,25 +475,60 @@
|
||||
if (options.requireValid && !checkValid()) {
|
||||
return;
|
||||
}
|
||||
onComplete(expressionEditor.getValue());
|
||||
var result;
|
||||
if (activeTab === "json-ui") {
|
||||
if (rootNode) {
|
||||
result = JSON.stringify(convertToObject(rootNode),null,4);
|
||||
} else {
|
||||
result = expressionEditor.getValue();
|
||||
}
|
||||
} else if (activeTab === "json-raw") {
|
||||
result = expressionEditor.getValue();
|
||||
}
|
||||
if (onComplete) { onComplete(result) }
|
||||
RED.tray.close();
|
||||
}
|
||||
}
|
||||
],
|
||||
resize: function(dimensions) {
|
||||
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");
|
||||
var height = $(".red-ui-editor-type-json-tab-content").height();
|
||||
$(".node-text-editor").css("height",(height-45)+"px");
|
||||
expressionEditor.resize();
|
||||
},
|
||||
open: function(tray) {
|
||||
var trayBody = tray.find('.red-ui-tray-body');
|
||||
var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor');
|
||||
|
||||
var container = $("#red-ui-editor-type-json-tab-ui-container").css({"height":"100%"});
|
||||
var filterDepth = Infinity;
|
||||
var list = $('<div class="red-ui-debug-msg-payload red-ui-editor-type-json-editor">').appendTo(container).treeList({
|
||||
rootSortable: false,
|
||||
sortable: ".red-ui-editor-type-json-editor-item-handle",
|
||||
}).on("treelistchangeparent", function(event, evt) {
|
||||
if (evt.old.type === 'array') {
|
||||
evt.old.element.find(".red-ui-editor-type-json-editor-label-type").text("array["+evt.old.children.length+"]");
|
||||
}
|
||||
if (evt.item.parent.type === 'array') {
|
||||
evt.item.parent.element.find(".red-ui-editor-type-json-editor-label-type").text("array["+evt.item.parent.children.length+"]");
|
||||
}
|
||||
}).on("treelistsort", function(event, item) {
|
||||
item.children.forEach(function(child,i) {
|
||||
if (item.type === 'array') {
|
||||
child.key = i;
|
||||
child.element.find(".red-ui-editor-type-json-editor-label-key")
|
||||
.text(child.key)
|
||||
.removeClass('red-ui-debug-msg-type-string')
|
||||
.addClass('red-ui-debug-msg-type-number');
|
||||
} else {
|
||||
child.element.find(".red-ui-editor-type-json-editor-label-key")
|
||||
.text('"'+child.key+'"')
|
||||
.removeClass('red-ui-debug-msg-type-number')
|
||||
.addClass('red-ui-debug-msg-type-string');
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
expressionEditor = RED.editor.createEditor({
|
||||
id: 'node-input-json',
|
||||
value: "",
|
||||
@@ -103,9 +553,56 @@
|
||||
expressionEditor.getSession().setValue(v||"",-1);
|
||||
});
|
||||
dialogForm.i18n();
|
||||
|
||||
var finishedBuild = false;
|
||||
var tabs = RED.tabs.create({
|
||||
element: $("#red-ui-editor-type-json-tabs"),
|
||||
onchange:function(tab) {
|
||||
activeTab = tab.id;
|
||||
$(".red-ui-editor-type-json-tab-content").hide();
|
||||
if (finishedBuild) {
|
||||
if (tab.id === "json-raw") {
|
||||
if (rootNode) {
|
||||
var result = JSON.stringify(convertToObject(rootNode),null,4);
|
||||
expressionEditor.getSession().setValue(result||"",-1);
|
||||
}
|
||||
|
||||
} else if (tab.id === "json-ui") {
|
||||
var raw = expressionEditor.getValue().trim() ||"{}";
|
||||
try {
|
||||
var parsed = JSON.parse(raw);
|
||||
rootNode = handleItem(null,parsed,0,null);
|
||||
rootNode.class = "red-ui-editor-type-json-root-node"
|
||||
list.treeList('data',[rootNode]);
|
||||
} catch(err) {
|
||||
rootNode = null;
|
||||
list.treeList('data',[{
|
||||
label: RED._("jsonEditor.error.invalidJSON")+err.toString()
|
||||
}]);
|
||||
}
|
||||
}
|
||||
}
|
||||
tab.content.show();
|
||||
trayOptions.resize();
|
||||
}
|
||||
})
|
||||
|
||||
tabs.addTab({
|
||||
id: 'json-raw',
|
||||
label: RED._('jsonEditor.rawMode'),
|
||||
content: $("#red-ui-editor-type-json-tab-raw")
|
||||
});
|
||||
tabs.addTab({
|
||||
id: 'json-ui',
|
||||
label: RED._('jsonEditor.uiMode'),
|
||||
content: $("#red-ui-editor-type-json-tab-ui")
|
||||
});
|
||||
finishedBuild = true;
|
||||
|
||||
|
||||
},
|
||||
close: function() {
|
||||
expressionEditor.destroy();
|
||||
// expressionEditor.destroy();
|
||||
if (options.onclose) {
|
||||
options.onclose();
|
||||
}
|
||||
|
@@ -32,13 +32,13 @@
|
||||
'<button type="button" class="red-ui-button" data-style="bq"><i class="fa fa-quote-left"></i></button>'+
|
||||
'<button type="button" class="red-ui-button" data-style="hr"><i class="fa fa-minus"></i></button>'+
|
||||
'<button type="button" class="red-ui-button" data-style="link"><i class="fa fa-link"></i></button>'+
|
||||
'</span>'
|
||||
'</span>'+
|
||||
'</div>';
|
||||
|
||||
var template = '<script type="text/x-red" data-template-name="_markdown">'+
|
||||
'<div id="red-ui-editor-type-markdown-panels">'+
|
||||
'<div id="red-ui-editor-type-markdown-panel-editor" class="red-ui-panel">'+
|
||||
'<div style="height: 100%; margin: auto; max-width: 1000px;">'+
|
||||
'<div style="height: 100%; margin: auto;">'+
|
||||
'<div id="red-ui-editor-type-markdown-toolbar"></div>'+
|
||||
'<div class="node-text-editor" style="height: 100%" id="red-ui-editor-type-markdown"></div>'+
|
||||
'</div>'+
|
||||
|
@@ -19,7 +19,7 @@ RED.keyboard = (function() {
|
||||
|
||||
var handlers = {};
|
||||
var partialState;
|
||||
RED.h = handlers;
|
||||
|
||||
var keyMap = {
|
||||
"left":37,
|
||||
"up":38,
|
||||
|
@@ -133,7 +133,7 @@ RED.library = (function() {
|
||||
icon: 'fa fa-folder',
|
||||
label: d,
|
||||
path: root+d+"/",
|
||||
children: function(item,done) {
|
||||
children: function(done, item) {
|
||||
loadLibraryFolder(library,type,root+d+"/", function(children) {
|
||||
item.children = children; // TODO: should this be done by treeList for us
|
||||
done(children);
|
||||
@@ -325,7 +325,7 @@ RED.library = (function() {
|
||||
|
||||
var menuOptionMenu = RED.menu.init({id:"red-ui-library-browser-menu",
|
||||
options: [
|
||||
{id:"red-ui-library-browser-menu-addFolder",label:"New folder", onselect: function() {
|
||||
{id:"red-ui-library-browser-menu-addFolder",label:RED._("library.newFolder"), onselect: function() {
|
||||
var defaultFolderName = "new-folder";
|
||||
var defaultFolderNameMatches = {};
|
||||
|
||||
@@ -431,11 +431,13 @@ RED.library = (function() {
|
||||
focus: function() {
|
||||
dirList.focus();
|
||||
},
|
||||
data: function(content) {
|
||||
data: function(content,selectFirst) {
|
||||
dirList.treeList('data',content);
|
||||
// setTimeout(function() {
|
||||
// dirList.treeList('select',content[0]);
|
||||
// },100);
|
||||
if (selectFirst) {
|
||||
setTimeout(function() {
|
||||
dirList.treeList('select',content[0]);
|
||||
},100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -788,7 +788,7 @@ RED.palette.editor = (function() {
|
||||
initInstallTab();
|
||||
})
|
||||
|
||||
packageList = $('<ol>',{style:"position: absolute;top: 78px;bottom: 0;left: 0;right: 0px;"}).appendTo(installTab).editableList({
|
||||
packageList = $('<ol>',{style:"position: absolute;top: 79px;bottom: 0;left: 0;right: 0px;"}).appendTo(installTab).editableList({
|
||||
addButton: false,
|
||||
scrollOnAdd: false,
|
||||
addItem: function(container,i,object) {
|
||||
|
@@ -17,7 +17,20 @@
|
||||
RED.palette = (function() {
|
||||
|
||||
var exclusion = ['config','unknown','deprecated'];
|
||||
var coreCategories = ['subflows', 'input', 'output', 'function', 'social', 'mobile', 'storage', 'analysis', 'advanced'];
|
||||
var coreCategories = [
|
||||
'subflows',
|
||||
'common',
|
||||
'function',
|
||||
'network',
|
||||
'input',
|
||||
'output',
|
||||
'sequence',
|
||||
'parser',
|
||||
'storage',
|
||||
'analysis',
|
||||
'social',
|
||||
'advanced'
|
||||
];
|
||||
|
||||
var categoryContainers = {};
|
||||
var sidebarControls;
|
||||
@@ -37,6 +50,7 @@ RED.palette = (function() {
|
||||
var catDiv = $('<div id="red-ui-palette-container-'+category+'" class="red-ui-palette-category hide">'+
|
||||
'<div id="red-ui-palette-header-'+category+'" class="red-ui-palette-header"><i class="expanded fa fa-angle-down"></i><span>'+label+'</span></div>'+
|
||||
'<div class="red-ui-palette-content" id="red-ui-palette-base-category-'+category+'">'+
|
||||
'<div id="red-ui-palette-'+category+'"></div>'+
|
||||
'<div id="red-ui-palette-'+category+'-input"></div>'+
|
||||
'<div id="red-ui-palette-'+category+'-output"></div>'+
|
||||
'<div id="red-ui-palette-'+category+'-function"></div>'+
|
||||
@@ -84,18 +98,36 @@ RED.palette = (function() {
|
||||
|
||||
var displayLines = [];
|
||||
|
||||
var currentLine = words[0];
|
||||
var currentLineWidth = RED.view.calculateTextWidth(currentLine, "red-ui-palette-label", 0);
|
||||
|
||||
for (var i=1;i<words.length;i++) {
|
||||
var newWidth = RED.view.calculateTextWidth(currentLine+" "+words[i], "red-ui-palette-label", 0);
|
||||
var currentLine = "";
|
||||
for (var i=0;i<words.length;i++) {
|
||||
var word = words[i];
|
||||
var sep = (i == 0) ? "" : " ";
|
||||
var newWidth = RED.view.calculateTextWidth(currentLine+sep+word, "red-ui-palette-label", 0);
|
||||
if (newWidth < nodeWidth) {
|
||||
currentLine += " "+words[i];
|
||||
currentLineWidth = newWidth;
|
||||
currentLine += sep +word;
|
||||
} else {
|
||||
displayLines.push(currentLine);
|
||||
currentLine = words[i];
|
||||
currentLineWidth = RED.view.calculateTextWidth(currentLine, "red-ui-palette-label", 0);
|
||||
if (i > 0) {
|
||||
displayLines.push(currentLine);
|
||||
}
|
||||
while (true) {
|
||||
var wordWidth = RED.view.calculateTextWidth(word, "red-ui-palette-label", 0);
|
||||
if (wordWidth >= nodeWidth) {
|
||||
// break word if too wide
|
||||
for(var j = word.length; j > 0; j--) {
|
||||
var s = word.substring(0, j);
|
||||
var width = RED.view.calculateTextWidth(s, "red-ui-palette-label", 0);
|
||||
if (width < nodeWidth) {
|
||||
displayLines.push(s);
|
||||
word = word.substring(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
currentLine = word;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
displayLines.push(currentLine);
|
||||
@@ -149,26 +181,28 @@ RED.palette = (function() {
|
||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||
}
|
||||
|
||||
function escapeNodeType(nt) {
|
||||
return nt.replace(" ","_").replace(".","_").replace(":","_");
|
||||
function getPaletteNode(type) {
|
||||
return $(".red-ui-palette-node[data-palette-type='"+type+"']");
|
||||
}
|
||||
|
||||
function escapeCategory(category) {
|
||||
return category.replace(/[ /.]/g,"_");
|
||||
}
|
||||
function addNodeType(nt,def) {
|
||||
var nodeTypeId = escapeNodeType(nt);
|
||||
if ($("#red-ui-palette-node_"+nodeTypeId).length) {
|
||||
if (getPaletteNode(nt).length) {
|
||||
return;
|
||||
}
|
||||
if (exclusion.indexOf(def.category)===-1) {
|
||||
var nodeCategory = def.category;
|
||||
|
||||
var originalCategory = def.category;
|
||||
var category = def.category.replace(/ /g,"_");
|
||||
if (exclusion.indexOf(nodeCategory)===-1) {
|
||||
|
||||
var originalCategory = nodeCategory;
|
||||
var category = escapeCategory(nodeCategory);
|
||||
var rootCategory = category.split("-")[0];
|
||||
|
||||
var d = document.createElement("div");
|
||||
d.id = "red-ui-palette-node_"+nodeTypeId;
|
||||
d.type = nt;
|
||||
var d = $('<div>',{class:"red-ui-palette-node"}).attr("data-palette-type",nt).data('category',rootCategory);
|
||||
|
||||
var label = /^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1];
|
||||
var label = nt;///^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1];
|
||||
if (typeof def.paletteLabel !== "undefined") {
|
||||
try {
|
||||
label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||"";
|
||||
@@ -178,51 +212,47 @@ RED.palette = (function() {
|
||||
}
|
||||
|
||||
$('<div/>', {
|
||||
class: "red-ui-palette-label"
|
||||
+ (((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-label-right" : "")
|
||||
class: "red-ui-palette-label"+(((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-label-right" : "")
|
||||
}).appendTo(d);
|
||||
|
||||
d.className="red-ui-palette-node";
|
||||
|
||||
if (def.icon) {
|
||||
var icon_url = RED.utils.getNodeIcon(def);
|
||||
var iconContainer = $('<div/>', {
|
||||
class: "red-ui-palette-icon-container"
|
||||
+ (((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-icon-container-right" : "")
|
||||
class: "red-ui-palette-icon-container"+(((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-icon-container-right" : "")
|
||||
}).appendTo(d);
|
||||
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||
}
|
||||
|
||||
d.style.backgroundColor = RED.utils.getNodeColor(nt,def);
|
||||
d.css("backgroundColor", RED.utils.getNodeColor(nt,def));
|
||||
|
||||
if (def.outputs > 0) {
|
||||
var portOut = document.createElement("div");
|
||||
portOut.className = "red-ui-palette-port red-ui-palette-port-output";
|
||||
d.appendChild(portOut);
|
||||
d.append(portOut);
|
||||
}
|
||||
|
||||
if (def.inputs > 0) {
|
||||
var portIn = document.createElement("div");
|
||||
portIn.className = "red-ui-palette-port red-ui-palette-port-input";
|
||||
d.appendChild(portIn);
|
||||
d.append(portIn);
|
||||
}
|
||||
|
||||
createCategory(def.category,rootCategory,category,(coreCategories.indexOf(rootCategory) !== -1)?"node-red":def.set.id);
|
||||
createCategory(nodeCategory,rootCategory,category,(coreCategories.indexOf(rootCategory) !== -1)?"node-red":def.set.id);
|
||||
|
||||
$("#red-ui-palette-"+category).append(d);
|
||||
|
||||
$(d).data('category',rootCategory);
|
||||
|
||||
d.onmousedown = function(e) { e.preventDefault(); };
|
||||
d.on("mousedown", function(e) { e.preventDefault();});
|
||||
|
||||
var popover = RED.popover.create({
|
||||
target:$(d),
|
||||
target:d,
|
||||
trigger: "hover",
|
||||
width: "300px",
|
||||
content: "hi",
|
||||
delay: { show: 750, hide: 50 }
|
||||
});
|
||||
$(d).data('popover',popover);
|
||||
|
||||
d.data('popover',popover);
|
||||
|
||||
// $(d).popover({
|
||||
// title:d.type,
|
||||
@@ -232,18 +262,20 @@ RED.palette = (function() {
|
||||
// html: true,
|
||||
// container:'body'
|
||||
// });
|
||||
$(d).on("click", function() {
|
||||
d.on("click", function() {
|
||||
RED.view.focus();
|
||||
var helpText;
|
||||
if (nt.indexOf("subflow:") === 0) {
|
||||
helpText = marked(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
} else {
|
||||
helpText = $("script[data-help-name='"+d.type+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
helpText = $("script[data-help-name='"+d.attr("data-palette-type")+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
}
|
||||
// Don't look too closely. RED.sidebar.info.set will set the 'Description'
|
||||
// section of the sidebar. Pass in the title of the Help section so it looks
|
||||
// right.
|
||||
RED.sidebar.info.set(helpText,RED._("sidebar.info.nodeHelp"));
|
||||
});
|
||||
var chart = $("#red-ui-workspace-chart");
|
||||
var chartOffset = chart.offset();
|
||||
var chartSVG = $("#red-ui-workspace-chart>svg").get(0);
|
||||
var activeSpliceLink;
|
||||
var mouseX;
|
||||
@@ -264,11 +296,12 @@ RED.palette = (function() {
|
||||
},
|
||||
stop: function() { d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false); if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null;}},
|
||||
drag: function(e,ui) {
|
||||
ui.originalPosition.left = $('#' + e.target.id).offset().left;
|
||||
var paletteNode = getPaletteNode(nt);
|
||||
ui.originalPosition.left = paletteNode.offset().left;
|
||||
|
||||
if (def.inputs > 0 && def.outputs > 0) {
|
||||
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();
|
||||
mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
|
||||
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop();
|
||||
if (!spliceTimer) {
|
||||
spliceTimer = setTimeout(function() {
|
||||
var nodes = [];
|
||||
@@ -330,13 +363,13 @@ RED.palette = (function() {
|
||||
|
||||
var nodeInfo = null;
|
||||
if (nt.indexOf("subflow:") === 0) {
|
||||
$(d).on("dblclick", function(e) {
|
||||
d.on("dblclick", function(e) {
|
||||
RED.workspaces.show(nt.substring(8));
|
||||
e.preventDefault();
|
||||
});
|
||||
nodeInfo = marked(def.info||"");
|
||||
}
|
||||
setLabel(nt,$(d),label,nodeInfo);
|
||||
setLabel(nt,d,label,nodeInfo);
|
||||
|
||||
var categoryNode = $("#red-ui-palette-container-"+rootCategory);
|
||||
if (categoryNode.find(".red-ui-palette-node").length === 1) {
|
||||
@@ -347,8 +380,7 @@ RED.palette = (function() {
|
||||
}
|
||||
|
||||
function removeNodeType(nt) {
|
||||
var nodeTypeId = escapeNodeType(nt);
|
||||
var paletteNode = $("#red-ui-palette-node_"+nodeTypeId);
|
||||
var paletteNode = getPaletteNode(nt);
|
||||
var categoryNode = paletteNode.closest(".red-ui-palette-category");
|
||||
paletteNode.remove();
|
||||
if (categoryNode.find(".red-ui-palette-node").length === 0) {
|
||||
@@ -360,8 +392,7 @@ RED.palette = (function() {
|
||||
}
|
||||
|
||||
function hideNodeType(nt) {
|
||||
var nodeTypeId = escapeNodeType(nt);
|
||||
var paletteNode = $("#red-ui-palette-node_"+nodeTypeId);
|
||||
var paletteNode = getPaletteNode(nt);
|
||||
paletteNode.hide();
|
||||
var categoryNode = paletteNode.closest(".red-ui-palette-category");
|
||||
var cl = categoryNode.find(".red-ui-palette-node");
|
||||
@@ -373,8 +404,7 @@ RED.palette = (function() {
|
||||
}
|
||||
|
||||
function showNodeType(nt) {
|
||||
var nodeTypeId = escapeNodeType(nt);
|
||||
var paletteNode = $("#red-ui-palette-node_"+nodeTypeId);
|
||||
var paletteNode = getPaletteNode(nt);
|
||||
var categoryNode = paletteNode.closest(".red-ui-palette-category");
|
||||
categoryNode.show();
|
||||
paletteNode.show();
|
||||
@@ -382,20 +412,15 @@ RED.palette = (function() {
|
||||
|
||||
function refreshNodeTypes() {
|
||||
RED.nodes.eachSubflow(function(sf) {
|
||||
var paletteNode = $("#red-ui-palette-node_subflow_"+sf.id.replace(".","_"));
|
||||
var paletteNode = getPaletteNode('subflow:'+sf.id);
|
||||
var portInput = paletteNode.find(".red-ui-palette-port-input");
|
||||
var portOutput = paletteNode.find(".red-ui-palette-port-output");
|
||||
|
||||
var paletteLabel = paletteNode.find(".red-ui-palette-label");
|
||||
paletteLabel.attr("class","red-ui-palette-label"
|
||||
+ (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-label-right" : "")
|
||||
);
|
||||
paletteLabel.attr("class","red-ui-palette-label" + (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-label-right" : ""));
|
||||
|
||||
var paletteIconContainer = paletteNode.find(".red-ui-palette-icon-container");
|
||||
paletteIconContainer.attr("class","red-ui-palette-icon-container"
|
||||
+ (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-icon-container-right" : "")
|
||||
);
|
||||
|
||||
paletteIconContainer.attr("class","red-ui-palette-icon-container" + (((!sf._def.align && sf.in.length !== 0 && sf.out.length === 0) || "right" === sf._def.align) ? " red-ui-palette-icon-container-right" : ""));
|
||||
|
||||
if (portInput.length === 0 && sf.in.length > 0) {
|
||||
var portIn = document.createElement("div");
|
||||
@@ -418,11 +443,11 @@ RED.palette = (function() {
|
||||
var currentCategory = paletteNode.data('category');
|
||||
var newCategory = (sf.category||"subflows");
|
||||
if (currentCategory !== newCategory) {
|
||||
var category = newCategory.replace(/ /g,"_");
|
||||
var category = escapeCategory(newCategory);
|
||||
createCategory(newCategory,category,category,"node-red");
|
||||
|
||||
var currentCategoryNode = paletteNode.closest(".red-ui-palette-category");
|
||||
var newCategoryNode = $("#palette-"+category);
|
||||
var newCategoryNode = $("#red-ui-palette-"+category);
|
||||
newCategoryNode.append(paletteNode);
|
||||
if (newCategoryNode.find(".red-ui-palette-node").length === 1) {
|
||||
categoryContainers[category].open();
|
||||
@@ -435,10 +460,9 @@ RED.palette = (function() {
|
||||
currentCategoryNode.find("i").toggleClass("expanded");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
paletteNode.css("backgroundColor", sf.color);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -446,7 +470,8 @@ RED.palette = (function() {
|
||||
var re = new RegExp(val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),'i');
|
||||
$("#red-ui-palette-container .red-ui-palette-node").each(function(i,el) {
|
||||
var currentLabel = $(el).find(".red-ui-palette-label").text();
|
||||
if (val === "" || re.test(el.id) || re.test(currentLabel)) {
|
||||
var type = $(el).attr("data-palette-type");
|
||||
if (val === "" || re.test(type) || re.test(currentLabel)) {
|
||||
$(this).show();
|
||||
} else {
|
||||
$(this).hide();
|
||||
@@ -459,8 +484,10 @@ RED.palette = (function() {
|
||||
.find(".red-ui-palette-node")
|
||||
.filter(function() { return $(this).css('display') !== 'none'}).length === 0) {
|
||||
categoryContainers[category].close();
|
||||
categoryContainers[category].container.slideUp();
|
||||
} else {
|
||||
categoryContainers[category].open();
|
||||
categoryContainers[category].container.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -538,23 +565,26 @@ RED.palette = (function() {
|
||||
sidebarControls.stop(false,true);
|
||||
sidebarControls.hide();
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
var categoryList = coreCategories;
|
||||
var userCategories = [];
|
||||
if (RED.settings.paletteCategories) {
|
||||
categoryList = RED.settings.paletteCategories;
|
||||
userCategories = RED.settings.paletteCategories;
|
||||
} else if (RED.settings.theme('palette.categories')) {
|
||||
categoryList = RED.settings.theme('palette.categories');
|
||||
userCategories = RED.settings.theme('palette.categories');
|
||||
}
|
||||
if (!Array.isArray(categoryList)) {
|
||||
categoryList = coreCategories
|
||||
if (!Array.isArray(userCategories)) {
|
||||
userCategories = [];
|
||||
}
|
||||
categoryList.forEach(function(category){
|
||||
createCategoryContainer(category, category, "palette.label."+category);
|
||||
});
|
||||
|
||||
var addedCategories = {};
|
||||
userCategories.forEach(function(category){
|
||||
addedCategories[category] = true;
|
||||
createCategoryContainer(category, escapeCategory(category), "palette.label."+escapeCategory(category));
|
||||
});
|
||||
coreCategories.forEach(function(category){
|
||||
if (!addedCategories[category]) {
|
||||
createCategoryContainer(category, escapeCategory(category), "palette.label."+escapeCategory(category));
|
||||
}
|
||||
});
|
||||
|
||||
var paletteFooterButtons = $('<span class="button-group"></span>').appendTo("#red-ui-palette .red-ui-component-footer");
|
||||
var paletteCollapseAll = $('<button type="button" class="red-ui-footer-button"><i class="fa fa-angle-double-up"></i></button>').appendTo(paletteFooterButtons);
|
||||
@@ -599,7 +629,6 @@ RED.palette = (function() {
|
||||
setTimeout(function() { $(window).trigger("resize"); } ,200);
|
||||
}
|
||||
|
||||
|
||||
function getCategories() {
|
||||
var categories = [];
|
||||
$("#red-ui-palette-container .red-ui-palette-category").each(function(i,d) {
|
||||
|
@@ -160,7 +160,7 @@ RED.projects.settings = (function() {
|
||||
if (activeProject.description) {
|
||||
desc = marked(activeProject.description);
|
||||
} else {
|
||||
desc = '<span class="red-ui-help-info-none">'+'No description available'+'</span>';
|
||||
desc = '<span class="red-ui-help-info-none">' + RED._("sidebar.project.noDescriptionAvailable") + '</span>';
|
||||
}
|
||||
var description = addTargetToExternalLinks($('<span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(desc)+'">'+desc+'</span>')).appendTo(container);
|
||||
description.find(".red-ui-text-bidi-aware").contents().filter(function() { return this.nodeType === 3 && this.textContent.trim() !== "" }).wrap( "<span></span>" );
|
||||
@@ -222,7 +222,7 @@ RED.projects.settings = (function() {
|
||||
if (summary) {
|
||||
container.text(summary).removeClass('node-info-node');
|
||||
} else {
|
||||
container.text(RED._("sidebar.project.projectSettings.noSummaryAvailable")).addClass('red-ui-help-info-none');
|
||||
container.text(RED._("sidebar.project.noSummaryAvailable")).addClass('red-ui-help-info-none');
|
||||
}
|
||||
}
|
||||
|
||||
|