Compare commits

...

296 Commits

Author SHA1 Message Date
Dave Conway-Jones
ea11aa7a0d add some part flush tests 2021-07-08 13:51:37 +01:00
Dave Conway-Jones
41c8ca8ab4 Delay node updates to added flush control for queuing 2021-07-08 12:13:23 +01:00
Nick O'Leary
b2f5a259ab Fix exec node test for gh-actions
The node adds `shell` to `execOpts` if `/bin/bash` exists. Clearly it
has not existed in Travis or running locally - but it does exist
on gh-action runner, so the test was failing.
2021-07-02 10:15:44 +01:00
Nick O'Leary
c8a0d3c10d Add error handling to exec test 2021-07-02 10:09:00 +01:00
Nick O'Leary
97df964051 Update changelog 2021-07-02 10:02:08 +01:00
Nick O'Leary
66dd05f8bc Merge branch 'master' into dev 2021-07-02 10:01:07 +01:00
Nick O'Leary
19589d9117 Merge branch 'master' into dev 2021-07-02 10:00:43 +01:00
Nick O'Leary
8147b2e0b1 Update changelog 2021-07-02 09:58:56 +01:00
Nick O'Leary
be22f8cd14 Update js-yaml 2021-07-02 09:39:19 +01:00
Nick O'Leary
868be9b7ff Update node-red-admin to 2.1 2021-07-02 09:37:14 +01:00
Nick O'Leary
5011281104 Merge branch 'dev' of github.com:node-red/node-red into dev 2021-07-02 09:22:56 +01:00
Nick O'Leary
42992c64ec Merge branch 'pr_3026' into dev 2021-07-02 09:22:35 +01:00
Nick O'Leary
2baff243ed Rename exec node hideWin option 2021-07-02 09:22:08 +01:00
Nick O'Leary
83440a6b0f Merge pull request #3047 from node-red/config-outliner-fix
Emit `nodes:change` for any updated config node when node deleted/added
2021-07-02 08:47:46 +01:00
Nick O'Leary
87c9a1c06c Include hasUser=false config nodes when exporting whole flow (#3048) 2021-07-01 21:40:57 +01:00
Nick O'Leary
b848fe249f Remove stray console.log from mqtt.html 2021-07-01 21:01:11 +01:00
Nick O'Leary
1e804d97ce Fix padding of compact notification
Closes #3045
2021-07-01 20:57:42 +01:00
Nick O'Leary
218d3c144b Emit nodes:change for any updated config node when node deleted/added 2021-07-01 20:52:13 +01:00
Nick O'Leary
05a4905490 Fix padding of compact notification
Closes #3045
2021-07-01 17:23:52 +01:00
Nick O'Leary
75103da378 Merge pull request #3044 from hardillb/hpagent-update
Bump hpagent to 0.1.2
2021-07-01 17:09:07 +01:00
Ben Hardill
9db9b53c81 Fix package.json
Also back out auth changes
2021-06-30 14:12:20 +01:00
Ben Hardill
0e4787f3e8 Bump hpagent to 0.1.2
Also remove workaround for empty proxy credentials
2021-06-30 13:42:56 +01:00
Nick O'Leary
f8d8d4b186 Update dependencies 2021-06-29 16:19:28 +01:00
Nick O'Leary
45e0a1ffea Merge pull request #3042 from node-red/bye-travis
Bye Travis. Hello GitHub Actions
2021-06-29 15:28:49 +01:00
Nick O'Leary
75c58093f1 Remove bye-travis branch trigger 2021-06-29 14:25:22 +01:00
Nick O'Leary
cc708e9fb4 Move to GH Actions in place of Travis 2021-06-29 14:19:24 +01:00
Nick O'Leary
2ce0e38827 Merge pull request #3040 from node-red/map-set-debug
Add support for Map/Set property types on Debug
2021-06-29 14:08:29 +01:00
Nick O'Leary
5b980e8c13 Merge pull request #3032 from node-red/view-annotations
Add RED.view.annotations api
2021-06-29 14:08:08 +01:00
Nick O'Leary
21b602650c Merge branch 'dev' of github.com:node-red/node-red into dev 2021-06-29 14:01:12 +01:00
Nick O'Leary
fa4b7a1a69 Ensure any html in changelog is escaped before displaying 2021-06-29 13:58:24 +01:00
Kazuhito Yokoi
977dfe700b Fix change log in help tab 2021-06-29 19:51:41 +09:00
Nick O'Leary
48ac50e1c9 Add support for Map/Set property types on Debug 2021-06-29 11:09:30 +01:00
Nick O'Leary
1a817947eb Merge pull request #3039 from kazuhitoyokoi/dev-fixfileinlabel
Fix output label in file-in node
2021-06-29 10:27:40 +01:00
Kazuhito Yokoi
be64603097 Fix indents from tab to space 2021-06-29 18:08:02 +09:00
Kazuhito Yokoi
f6b90c8271 Fix output label in file-in node 2021-06-29 18:02:06 +09:00
Kazuhito Yokoi
26e4be87c7 Add Japanese translation for file-in node (#3037) 2021-06-29 08:42:16 +01:00
Nick O'Leary
cddbb8d80d Merge pull request #3035 from node-red/file-node-msg-clone-option
Add option for file-in node to include all properties (default off)
2021-06-28 15:48:12 +01:00
Nick O'Leary
58023b4bf0 Merge branch 'pr_3024' into dev 2021-06-28 15:32:32 +01:00
Nick O'Leary
4f18a5f1c3 Merge pull request #3025 from node-red/comms-batch
Batch messages sent over Comms link
2021-06-28 15:28:40 +01:00
Nick O'Leary
56df8d8bd3 Merge pull request #3031 from Steve-Mcl/monaco0252
Update Monaco Editor to V0.25.2 (latest)
2021-06-28 15:28:09 +01:00
Nick O'Leary
211ec104c2 Merge pull request #3015 from Steve-Mcl/monaco-beta-bug-fix
Patches for Monaco editor
2021-06-28 15:27:27 +01:00
Nick O'Leary
3fb573247d Add 'theme' to default settings file 2021-06-25 18:10:13 +01:00
Dave Conway-Jones
6aac44db14 Add option for file-in node to include all properties (default off)
and add test
2021-06-25 14:39:18 +01:00
Nick O'Leary
3255e11cfc Limit annotations to badge type 2021-06-24 17:59:32 +01:00
Nick O'Leary
844bf29de1 Add RED.view.annotations api 2021-06-24 17:40:26 +01:00
Steve-Mcl
04d91d1422 prevent promise rejection when loading editor 2021-06-24 11:28:39 +01:00
Steve-Mcl
db90e1f801 remove unnecessary global uncaught promise handler
- monaco issue https://github.com/microsoft/monaco-editor/issues/2382
2021-06-24 11:27:24 +01:00
Steve-Mcl
7f30748a41 dont try to load en-gb or en-us (they're builtin)
- also monaco now comes with Turkish, Polish, Portuguese, Czech langs
2021-06-24 11:25:26 +01:00
Steve-Mcl
a4e0abb48f Update monaco editor to V0.5.2 2021-06-24 11:21:49 +01:00
Steve-Mcl
3f27dc89d8 Add overloads for context/flow/global set/get/keys 2021-06-23 22:27:13 +01:00
Nick O'Leary
d6f6efc189 Lower tray zIndex when overlay tray being opened
Fixes #3019
2021-06-23 14:34:52 +01:00
Nick O'Leary
2cda49fc38 Reduce z-Index of Function expand buttons to prevent overlap
Part of #3019
2021-06-23 14:16:36 +01:00
Nathanaël Lécaudé
04f4a76b41 exec node: clarify scope 2021-06-18 14:46:16 -04:00
Steve-Mcl
0a8f7085f3 allow static private field to have initializer 2021-06-17 08:44:44 +01:00
Nathanaël Lécaudé
7ae48d7390 exec: solidify tests 2021-06-16 17:38:34 -04:00
Steve-Mcl
c908502644 add 2 ace compatible functions
- clearSelection - blocky node
- selectAll - obvious addition
2021-06-16 22:36:00 +01:00
Nathanaël Lécaudé
2f0631809d exec node: modify test 2021-06-16 17:09:21 -04:00
Nathanaël Lécaudé
91ab3bd972 exec node: add windowsHide option to hide windows under Windows 2021-06-16 17:00:00 -04:00
Sam Machin
672636313c Update packages/node_modules/@node-red/runtime/locales/en-US/runtime.json
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2021-06-16 17:13:52 +01:00
Nick O'Leary
79875ef50d Merge branch 'master' into dev 2021-06-16 17:03:50 +01:00
Nick O'Leary
aea5445495 Support loading external module sub path
Fixes #3023
2021-06-16 17:02:24 +01:00
Nick O'Leary
754a36fbc9 Merge branch 'master' into dev 2021-06-16 13:42:56 +01:00
Nick O'Leary
85dafc0b3c Ensure RED.clipboard.import displays the right library
Fixes #3021
2021-06-16 13:41:58 +01:00
Nick O'Leary
b516ab9b4f Batch messages sent over comms to prevent flooding 2021-06-16 11:45:02 +01:00
Nick O'Leary
1a27e60e55 Allow RED.popover.panel to specify a closeButton to ignore click events on 2021-06-16 11:44:40 +01:00
Nick O'Leary
2c710736e8 Use browser default language for initial page load 2021-06-16 11:44:35 +01:00
Nick O'Leary
69b9ff69be Add css var for node font color 2021-06-16 11:44:30 +01:00
Nick O'Leary
a3a4fc0cc2 Fix label padding of toggleButton 2021-06-16 11:44:25 +01:00
Nick O'Leary
ae686bb15d Give sidebar open tab a bit more room for its label 2021-06-16 11:44:20 +01:00
Nick O'Leary
68a5325849 Bump version to 2.0.0-beta.2 2021-06-16 11:44:14 +01:00
Nick O'Leary
75e3bddfa9 Remove the request module as a dependency 2021-06-16 11:44:09 +01:00
Sam Machin
bd3a8db438 log readOnly on startup 2021-06-16 10:10:31 +01:00
Nick O'Leary
102868bf74 Merge pull request #3022 from kazuhitoyokoi/update-message-files
Add additional Japanese translations for Node-RED 2.0 beta-1
2021-06-15 23:28:19 +01:00
Steve-Mcl
1a73a27102 add diagnosticCodesToIgnore 2345
- handles issue with Intl.DateTimeFormat when `options` is a variable
2021-06-15 23:15:54 +01:00
Steve-Mcl
a9cf34ab56 prevent IE script error
- even though monaco does not work in EI, scripts must not fail to load
2021-06-15 21:02:30 +01:00
Steve-Mcl
46d17c3314 update code comments 2021-06-15 21:01:33 +01:00
Nick O'Leary
40f816c311 Merge pull request #3020 from node-red-hitachi/update-message-files
Update message catalogue
2021-06-15 08:53:02 +01:00
Kazuhito Yokoi
13f1c12912 Add translations to message catalog 2021-06-14 15:54:05 +09:00
Hiroyasu Nishiyama
93c25f5d1b Update message catalogue 2021-06-13 14:19:36 +09:00
Steve-Mcl
aa6ec60c34 fix up issues with function node types
- node.status add overload
- remove examples as they dont render correctly
- correct Number and Object types to number and object
2021-06-11 18:44:37 +01:00
Nick O'Leary
ac159bb52e Merge pull request #3017 from hardillb/dev
Fix for basic auth with @ in username
2021-06-11 14:51:38 +01:00
Ben Hardill
919aee64f9 Add support for user/pass in URL 2021-06-11 14:48:41 +01:00
Ben Hardill
553bec1a1f Add testcase 2021-06-11 14:34:16 +01:00
Ben Hardill
bcb6d1cf93 Fix for basic auth with @ in username 2021-06-11 14:25:18 +01:00
Steve-Mcl
7d24e5b279 node.status snippet enums for fill and shape 2021-06-11 08:01:38 +01:00
Steve-Mcl
12253e23b5 Add setReadOnly support 2021-06-10 21:18:29 +01:00
Nick O'Leary
4acb66fb7a Merge branch 'master' into dev 2021-06-10 16:06:30 +01:00
Nick O'Leary
68ef85b64b Update CHANGELOG 2021-06-10 15:48:24 +01:00
Dave Conway-Jones
b73efe6bb4 Ensure CSV node tries to parse number when set to do so (trim whitespace) 2021-06-10 14:55:47 +01:00
Nick O'Leary
89c84522d2 Merge branch 'master' into dev 2021-06-10 14:19:24 +01:00
Nick O'Leary
98172764ac Handle node icon paths for scoped modules
Fixes #3013
2021-06-10 14:15:43 +01:00
Nick O'Leary
448e881104 Update to latest node-red-admin 2021-06-10 10:31:54 +01:00
Nick O'Leary
f16134ab1f Update changelog 2021-06-09 13:49:33 +01:00
Nick O'Leary
f5dc1564a4 Merge pull request #3009 from hardillb/get-got
Get got - deactivate HTTP - Proxy unit tests
2021-06-09 09:59:31 +01:00
Nick O'Leary
133df75bd4 Merge branch 'dev' into get-got 2021-06-09 09:59:23 +01:00
Nick O'Leary
440be0653a Merge pull request #3012 from node-red/reorganise-settings
Restructure default settings.js to be more organised
2021-06-09 09:57:34 +01:00
Nick O'Leary
d721a40ca5 Clarify flowFilePretty option 2021-06-09 09:26:55 +01:00
Nick O'Leary
a9b252b8fa Ensure httpServerOptions gets applied to ALL the express apps
This is silly. Turns out setting options at a top level app
does not percolate down to sub apps (and vice versa). You
have to apply the options to ALL express apps.
2021-06-08 21:17:42 +01:00
Nick O'Leary
8a5b3ddee7 Change comment style in default settings file.
Makes clearer what is a comment and what is commented-out code.
2021-06-08 21:04:59 +01:00
Nick O'Leary
d83e543a98 Update dependencies 2021-06-08 17:33:40 +01:00
Nick O'Leary
bcd6e8fd63 Restructure default settings.js to be more organised 2021-06-08 15:58:19 +01:00
Ben Hardill
d5c5738aab Fix proxy authentication problem & reinstate tests
Down to only 2 of the previous tests not working
2021-06-08 14:22:20 +01:00
Ben Hardill
9e4dfe081f Remove unused dev dependency 2021-06-08 13:27:26 +01:00
Ben Hardill
090852b72b Revet changes to /proxyAuthneticate
This end point is currently not hit
2021-06-08 12:06:18 +01:00
Nick O'Leary
ff5e038c49 Improve contrast of export dialog JSON font color 2021-06-08 11:54:58 +01:00
Nick O'Leary
5cc2e5f6e1 Fix merge 2021-06-08 11:48:45 +01:00
Ben Hardill
4e8c0573c4 Re-enable as many http-request proxy tests as possible 2021-06-08 11:46:54 +01:00
Nick O'Leary
ce905ba2c4 Merge branch 'master' into dev 2021-06-08 11:44:31 +01:00
Nick O'Leary
3104c17fb3 Update to latest node-red-admin 2021-06-08 11:36:16 +01:00
Nick O'Leary
7651941722 Do not assign z property to tab node when updating flow
Fixes #3010
2021-06-08 11:35:43 +01:00
Nick O'Leary
7bf938901a Merge branch 'pr_2952' into dev 2021-06-08 11:09:56 +01:00
Nick O'Leary
f8b61d2926 Merge pull request #2997 from hardillb/watch-fix
Watch node throws errors if new files deleted
2021-06-08 11:07:37 +01:00
Nick O'Leary
4edea59ab1 Merge branch 'pr_2990' into dev 2021-06-08 10:56:57 +01:00
Nick O'Leary
c8bcd2818d Disable inject-now button if inside subflow 2021-06-08 10:56:34 +01:00
Nick O'Leary
9b46dbaff1 Switch editableList buttons from <a> to <button> elements 2021-06-08 10:56:04 +01:00
Ben Hardill
17a139f27f Start to add HTTP-PROXY tests back in 2021-06-08 10:30:24 +01:00
Nick O'Leary
bd00c728d1 Merge pull request #3008 from Steve-Mcl/node-red-typings-update
Node red typings update
2021-06-08 10:29:03 +01:00
Nick O'Leary
9d510b514c Merge pull request #3007 from Steve-Mcl/monaco-update
update monaco v0.24.0
2021-06-08 10:27:15 +01:00
Nick O'Leary
00dcc5ecda Merge pull request #3011 from node-red/cheerio-update
HTML node: cheerio update to 1.x
2021-06-08 10:22:20 +01:00
Nick O'Leary
dbbdd3f799 Update to latest cheerio module 2021-06-08 09:31:27 +01:00
Nick O'Leary
3541b4b968 Merge pull request #3004 from node-red-hitachi/fix-get-subflow-info
Fix allow Flow.getNode to return subflowInstance nodes
2021-06-07 18:16:01 +01:00
Nick O'Leary
5b1bf35a23 Fix over-greeding matching whilst parsing commit history
Fixes #3006
2021-06-07 18:07:58 +01:00
Ben Hardill
591b61945f Merge branch 'get-got' of github.com:hardillb/node-red into get-got 2021-06-07 16:01:06 +01:00
Ben Hardill
bd1943626b Add more comment 2021-06-07 16:00:07 +01:00
Ben Hardill
f152cdef51 Merge pull request #1 from node-red/get-got
Get got
2021-06-07 13:04:27 +01:00
Ben Hardill
33f8c9747d Comment out HTTP Proxy tests
These have been removed because the mock proxy doesn't
support using the HTTP CONNECT verb and the new Got based
http-request node only uses CONNET for proxied content
2021-06-07 13:00:02 +01:00
Steve-Mcl
714a5e26b3 add env.get to function node defs 2021-06-05 12:42:54 +01:00
Steve-Mcl
7f2c6e40d3 fix typescript errors in node-red d.ts def files 2021-06-05 12:42:13 +01:00
Steve-Mcl
db676ec223 add snippet for env.get 2021-06-05 12:34:47 +01:00
Steve-Mcl
ffb3e511a7 update monaco v0.24.0 2021-06-05 12:28:25 +01:00
Nick O'Leary
e9e64f6a44 Add option to RED.nodes.createCompleteNodeSet to include node dimensions
This allows the linter to use a flow json with more than just position
information.
2021-06-04 13:53:01 +01:00
Kazuhiro Ito
a7b8adb0e1 Fix allow Flow.getNode to return subflowInstance nodes 2021-06-04 15:08:03 +09:00
Jiye Yu
4140ff03d7 fix typo in zh-CN translation (#3003) 2021-06-03 19:03:00 +01:00
Nick O'Leary
e042ef05a4 Update dependencies 2021-06-02 16:24:12 +01:00
Nick O'Leary
7c02e4d66a Merge branch 'master' into dev 2021-06-02 15:40:56 +01:00
Nick O'Leary
711794cfe1 Merge pull request #2993 from Steve-Mcl/master
ensure context get/set key is a string
2021-06-02 15:20:25 +01:00
Nick O'Leary
c0e4cf2358 Fix handling of boolean subflow module properties
Fixes #3000
2021-06-02 14:48:54 +01:00
Nick O'Leary
a92f8f36c1 Keep proper track of moved/changed state in undo/redo history
Fixes #2999
2021-06-02 14:07:22 +01:00
Nick O'Leary
12698dc347 Add full ast parsing in Function node to spot node.done calls
Fixes #2998
2021-06-02 12:32:44 +01:00
Nick O'Leary
3e6a55f78e Update to latest 6.x ws module 2021-06-02 11:58:51 +01:00
Ben Hardill
7585f14b89 Watch node throws errors if new files deleted
before the node has finished processing them all.

Fixes #2996
2021-05-28 08:34:08 +01:00
Nick O'Leary
01b5fc4d49 Merge pull request #2987 from node-red/clean-ids
Change node id generation to give fixed length values without '.'
2021-05-27 12:18:38 +01:00
Nick O'Leary
0fb7d3bfc8 Merge pull request #2991 from node-red-hitachi/fix-empty-switch-rule
fix handling of empty switch rules
2021-05-27 12:18:23 +01:00
Nick O'Leary
2cd74d355c Merge pull request #2994 from node-red/css-vars
Add css named variables for certain key colours
2021-05-27 12:18:05 +01:00
Nick O'Leary
3d405f8c63 Merge pull request #2969 from node-red/ajv-update
Update ajv to 8.2.0 - drop support for JSON-Schema draft-04
2021-05-27 12:17:51 +01:00
Steve-Mcl
a92f0c4c6e fix context key validation + add tests
- adds a helper function validateContextKey to keep it DRY
- adds tests ensure key of null "" 1 {} [] [""] [1] [{}] all throw error
2021-05-26 13:04:09 +01:00
Nick O'Leary
de142ac9d6 Add css named variables for certain key colors 2021-05-25 21:03:01 +01:00
Nick O'Leary
468ef7ecff Allow RED.settings.set to replace string property with object property 2021-05-25 21:02:14 +01:00
Steve-Mcl
4d768fd236 ensure context get/set key is a string 2021-05-25 14:53:06 +01:00
Steve-Mcl
bfc1f95190 remove redundant i18n entries
- no longer needed since moving inject onto edit form
2021-05-25 13:53:59 +01:00
Nick O'Leary
bc17ebd90e Fix css of node help table of contents elements 2021-05-24 10:23:00 +01:00
Hiroyasu Nishiyama
bb1b3727cb add test case 2021-05-23 10:42:28 +09:00
Hiroyasu Nishiyama
4dbebefb45 fix handling empty rules 2021-05-23 10:01:45 +09:00
Steve-Mcl
e1c5764fbf move new inject button to existing edit form
- revert refactoring of building editableList (not needed now)
- remove node button modifier click & tray.show feature
- add inject button to editableList [buttons] array
- add `id` option to editableList to permit DOM access after creation
- get the new inject button via its `id` and float it to the right
- removed the popup tray buttons i18n entries
2021-05-22 10:52:44 +01:00
Steve-Mcl
70f975e4f0 move inject button off dialog and onto form 2021-05-21 13:26:50 +01:00
Steve-Mcl
845567d1ba add 2 tests for user inject values 2021-05-20 22:53:32 +01:00
Steve-Mcl
f570447000 i18n for buttons on user inject values 2021-05-20 22:53:10 +01:00
Steve-Mcl
9d7b8f1f2f change user prop name for injected values
- less chance for collision
2021-05-20 22:35:42 +01:00
Steve-Mcl
bae6bfc32d Add inject values without deploy feature 2021-05-20 21:12:32 +01:00
Nick O'Leary
8a63390464 Merge pull request #2988 from hardillb/ALPNProtocols
Add ALPN support to TLS node
2021-05-19 17:39:19 +01:00
Ben Hardill
0b52cd8b31 Fixes from testing
I set up a NGINX instance to test this and found I'd missed some bits.

Still can't find a way to test this easily from a nodejs unit test
2021-05-19 10:41:24 +01:00
Nick O'Leary
f97569dd34 Clarify codeEditor options only relate to monaco 2021-05-18 16:46:16 +01:00
Nick O'Leary
a9164e63ab Merge branch 'dev' into pr_2971 2021-05-18 16:30:13 +01:00
Ben Hardill
8c95067ec4 Add ALPN support to TLS node 2021-05-18 13:13:32 +01:00
Nick O'Leary
4f77bbeb2b Update for 1.3.5 2021-05-18 11:52:49 +01:00
Nick O'Leary
8bbed2c831 Change node id generation to give fixed length values without '.' 2021-05-18 11:32:17 +01:00
Nick O'Leary
6b43a23c4b Merge branch 'master' into dev 2021-05-14 21:18:32 +01:00
Nick O'Leary
be9521f659 Revert some of #2967 to fix treeList gutter width calculation 2021-05-14 21:17:47 +01:00
Nick O'Leary
90761fd840 Fix 'SyntaxError' in Function node when last line of on-stop is a comment 2021-05-13 17:23:25 +01:00
Nick O'Leary
d49d9a783c Merge branch 'master' into dev 2021-05-13 16:06:33 +01:00
Nick O'Leary
d7dc7c4eda Fix error handling in runtime/lib/api/nodes 2021-05-13 15:46:56 +01:00
Nick O'Leary
fe64c6a841 Merge branch 'master' into dev 2021-05-13 14:30:02 +01:00
Nick O'Leary
2bbdc85a29 Prevent unknown node from breaking editor
If a node provides a .js file that registers a type
but its .html is empty, then the editor will know about
the type, but there will be no node definition.

This fix handles that in some of the utility functions
for generating node appearance.

This wasn't an exhaustive check for these things - just
some obvious candidates that I hit in testing 'bad' nodes
2021-05-13 14:28:01 +01:00
Nick O'Leary
74628b7034 Update debug tests to handle compact comms format 2021-05-13 14:18:11 +01:00
Nick O'Leary
15aa249f64 Stop module with missing types from preventing editor load 2021-05-13 14:06:43 +01:00
Nick O'Leary
fdf58e1225 Fix lint errors in editor hooks 2021-05-13 14:00:21 +01:00
Nick O'Leary
866f305686 Open subflow tab next to active tab rather than at the end 2021-05-13 13:57:29 +01:00
Nick O'Leary
1550e5343c Merge branch 'master' into dev 2021-05-13 13:42:26 +01:00
Nick O'Leary
add3dd1077 Merge pull request #2986 from hardillb/get-got
Fix msg.responseUrl
2021-05-13 13:41:58 +01:00
Nick O'Leary
79a142fb19 Fix error log in runtime hooks module 2021-05-13 13:40:42 +01:00
Nick O'Leary
1a30fe4a1a Improve red-ui-node-icon css and add red-ui-node-icon-small modifier class 2021-05-13 13:39:29 +01:00
Nick O'Leary
4ff991764e Updates to encode/decode message when passed over debug comms link 2021-05-13 13:38:34 +01:00
Nick O'Leary
001f066769 Remove all input event listeners on a node once it is closed
This prevents in-flight messages being passed to the node after
it has closed.
2021-05-13 13:37:21 +01:00
Nick O'Leary
c47b553a8e Add viewAddPort viewRemovePort viewAddNode viewRemoveNode hooks to view 2021-05-13 13:36:50 +01:00
Nick O'Leary
319af51f84 Add RED.hooks to editor 2021-05-13 13:35:12 +01:00
Nick O'Leary
5dbaaae68e Merge branch 'master' into dev 2021-05-12 16:00:36 +01:00
Ben Hardill
8c1a749a5a Fix msg.responseUrl
The original version would pick up the proxy servers port number
2021-05-12 11:08:57 +01:00
Nick O'Leary
fc8643f238 Merge pull request #2983 from hardillb/get-got
Get got working with proxies
2021-05-12 09:41:26 +01:00
Nick O'Leary
c8653f19bf Merge pull request #2985 from node-red-hitachi/update-function-node-info-text
Update Japanese info text of function node
2021-05-12 09:41:09 +01:00
Hiroyasu Nishiyama
b01100d818 Update Japanese info text of function node 2021-05-12 08:54:32 +09:00
Nick O'Leary
d4096a9026 Merge pull request #2984 from node-red/migrate-sass
Migrate to sass module from node-sass
2021-05-11 18:56:06 +01:00
Nick O'Leary
b9e780cdcd Add Node 16 with sass fixed 2021-05-11 18:14:05 +01:00
Nick O'Leary
b77cd56a01 Migrate from node-sass to sass
node-sass is deprecated and doesn't work on Node 16.
sass is actively maintained and considered the canonical sass
implementation.
2021-05-11 18:13:21 +01:00
Nick O'Leary
9cdec156dc Merge pull request #2974 from aheissenberger/fix-bundle-error
Fixed esbuild bundle error "installRetry" was declared a constant and changed
2021-05-11 17:45:07 +01:00
Nick O'Leary
6aa5968863 Fix Function tab label names in the node help text
Closes #2978
2021-05-11 17:15:27 +01:00
Nick O'Leary
8f7686cd7b Handle sidebar tab that no longer exists when setting first active 2021-05-11 16:42:32 +01:00
Nick O'Leary
d8d384a979 Fix plugin loading when browser sends unrecognised lang 2021-05-11 16:42:00 +01:00
Nick O'Leary
ade318bb78 Support mousewheel scroll in tab bar 2021-05-11 15:58:01 +01:00
Nick O'Leary
ed3aa8189f Shrink default notification box
Also reduces Inject/Debug notification display time as 5 seconds is a
long time for a message telling you it worked
2021-05-11 14:45:53 +01:00
Nick O'Leary
3e43597617 Prevent error whilst drag/drop importing from leaving dropTarget visible
Fixes #2982
2021-05-11 14:10:40 +01:00
Ben Hardill
4c8e895ac7 Clean up console.logs 2021-05-11 09:56:22 +01:00
Ben Hardill
f6a3671366 Get the http-request node got port working with Proxy 2021-05-10 23:01:29 +01:00
Nick O'Leary
e641b0a965 Fix scaling issues when dragging nodes into scaled workspace 2021-05-10 21:03:27 +01:00
Hiroyasu Nishiyama
eddddc6c9b fix duplicate csv node example (#2980) 2021-05-10 15:39:23 +01:00
Nick O'Leary
f249d6306f Merge pull request #2976 from kazuhitoyokoi/master-fixinfotips
Fix incorrect shortcut keys in info tips
2021-05-10 09:42:59 +01:00
Kazuhito Yokoi
5c31bd54e4 Fix incorrect shortcut keys in info tips 2021-05-06 20:09:35 +09:00
Nick O'Leary
71ba73b38f Merge branch 'master' into dev 2021-05-04 11:19:05 +01:00
Nick O'Leary
db0ff74857 Reduce code duplication around node/label generation 2021-05-04 11:12:55 +01:00
Steve-Mcl
1acb073737 add support for explicit calls to ace.setFontSize
- found node-red-contrib-ui-svg explicitly calling ace function
2021-05-04 10:34:29 +01:00
Steve-Mcl
251dda3652 missing editor destroy() calls 2021-05-04 09:04:13 +01:00
Steve-Mcl
22db24509d Ensure monaco exists before attempting cleanup 2021-05-04 09:03:35 +01:00
Andreas Heissenberger
54c9d27fd8 fix 2021-05-03 17:35:50 +02:00
Andreas Heissenberger
01888ff078 fix "installRetry" was declared a constant and changed 2021-05-03 17:23:27 +02:00
Steve-Mcl
ffbd140a97 bug fix orphaned models and graphical tray glitch
- ensure models are disposed correctly
- clean up any orphaned models left after editor:close
- improve concurrent multiple instances javascript models
- fix graphical glitch
2021-05-03 16:19:01 +01:00
Steve-Mcl
dedf5c52d9 better support for multiple editors
- as the javascript model is singleton, need to disable
syntax checking when editor not focused
(support multiple instances of js editor (function node))
2021-05-02 23:11:29 +01:00
Steve-Mcl
10465c5d68 treat appcache files as shell (uibuilder support) 2021-05-02 23:00:35 +01:00
Steve-Mcl
1f4f64a7c0 handle node-red style affecting monaco rename box 2021-05-02 22:44:48 +01:00
Steve-Mcl
a6f116b57b add default basic entries in settings,js
- defaults to "ace" but provides instruction for using monaco
2021-05-01 22:17:48 +01:00
Steve-Mcl
0a80186a92 Merge branch 'dev' into monaco2 2021-05-01 21:56:45 +01:00
Nick O'Leary
635bdf15cb Fix use of paletteLabel in help tab
Fixes #2973
2021-05-01 21:55:50 +01:00
Steve-Mcl
a72bdfdacc Handle known bug (monaco-editor issue No 2382)
- handles "Uncaught (in promise) Canceled: Canceled"
2021-05-01 11:40:43 +01:00
Steve-Mcl
dc3e04456c remove temporary debugging window variable 2021-05-01 11:01:04 +01:00
Nick O'Leary
b0e4fb7602 Fix infotip display following i18n update 2021-04-30 13:54:25 +01:00
Steve-Mcl
df7aa3339b dont tokenise JSONata
- monaco has jsonata tokeniser
2021-04-29 18:11:47 +01:00
Steve-Mcl
c475536388 provide extra libs and call to refresh 2021-04-29 18:00:23 +01:00
Steve-Mcl
cc7def89af ensure monaco is correctly sized 2021-04-29 17:59:12 +01:00
Steve-Mcl
58da87898e integrate monaco
- refactors createEditor out to own code files
- moves ace editor to own code file
- adds monaco editor to own code file
- add monaco bootstrap
- update mst to include monaco asset
- update grunt to include new files and integrate
2021-04-29 17:58:41 +01:00
Steve-Mcl
bded5490d2 add utility func getBrowserInfo
- prep for monaco - for slimming down monaco on mobile
- prep for monaco - needed to prevent monaco on IE
2021-04-29 17:35:11 +01:00
Steve-Mcl
c3715a2a3d ensure editor is removed
- Fixes issue with left over HTML in the DOM
2021-04-29 17:32:44 +01:00
Steve-Mcl
abf084f6c2 Dont call to ACE, re-use createEditor instead 2021-04-29 17:31:38 +01:00
Steve-Mcl
37ba409dc3 ensure mode is set for event log viewer 2021-04-29 17:29:54 +01:00
Steve-Mcl
f29488b24f prevent editor context menu being clipped by sidebar
- raise / lower tray z-index for correct slide animation
2021-04-29 17:03:17 +01:00
Steve-Mcl
71bdade7b9 prevent exception if ace is missing 2021-04-29 16:59:11 +01:00
Steve-Mcl
60d97c887d missing args from JSONata $now signature 2021-04-29 16:57:22 +01:00
Steve-Mcl
5bba50f01f refactor node.libs to a function getLibsList
- preparation for monaco integration
2021-04-29 16:56:16 +01:00
Steve-Mcl
1f7884dc70 add typings for basic intellisense 2021-04-29 16:54:29 +01:00
Steve-Mcl
69dafd6c68 add codeEditor settings 2021-04-29 16:53:59 +01:00
Steve-Mcl
64b79cd5ac add monaco dist
- includes themes from https://github.com/brijeshb42/monaco-themes
2021-04-29 16:52:22 +01:00
Nick O'Leary
1af21735a9 Fix theme handling when no editorTheme.page setting 2021-04-29 15:32:26 +01:00
Nick O'Leary
9886af3cec Fix jshint error in treeList 2021-04-29 14:09:21 +01:00
Nick O'Leary
caa98b08da Merge branch 'pr_2965' into dev 2021-04-29 11:04:50 +01:00
Nick O'Leary
00caa13a12 Update externalModules_spec to handle variable npm args length 2021-04-29 11:04:19 +01:00
Nick O'Leary
cfc0135e86 Update ajv to 8.2.0 - drop support for JSON-Schema draft-04 2021-04-29 10:48:26 +01:00
Nick O'Leary
1d4dd4be96 Merge pull request #2961 from node-red/rerorder-inject-typedinput
Re-order inject typedinput to de-emphasise context options
2021-04-28 21:56:47 +01:00
nileio
676f790933 add engine-strict flag to npm install args 2021-04-28 22:40:17 +10:00
Nick O'Leary
9f2a2b9869 Pass npm args to preUninstall hook to be consistent with preInstall 2021-04-27 17:32:18 +01:00
Nick O'Leary
a0c09fc617 Update api docs header 2021-04-27 17:30:30 +01:00
Dave Conway-Jones
19d391fa05 only move msg. instead 2021-04-27 11:28:01 +01:00
Dave Conway-Jones
d1aa1fd4d8 reorder inject typedinput to de-empahsise context options 2021-04-27 11:15:16 +01:00
Nick O'Leary
4133f9c56f Merge pull request #2936 from node-red/npm-install-hooks
Add pre/postInstall hooks to npm install handling
2021-04-27 10:57:14 +01:00
Nick O'Leary
53055064e1 Merge pull request #2932 from node-red/file-cwd-setting
File node: Add fileWorkingDirectory to customise how relative paths are resolved
2021-04-27 10:49:02 +01:00
Nick O'Leary
06090d8de1 Merge branch 'dev' into pr_2949 2021-04-27 10:45:33 +01:00
Nick O'Leary
d6ccae38f8 Merge pull request #2959 from node-red/inject-cronosjs
Move Inject node to CronosJS module
2021-04-27 10:44:22 +01:00
Nick O'Leary
f7210effec Rework hooks structure to be a linkedlist
Allows for safe removal of hooks whilst they are being invoked
2021-04-26 21:14:42 +01:00
Nick O'Leary
ea50ba16f9 Move Inject node to CronosJS module 2021-04-26 14:47:50 +01:00
Nick O'Leary
b62e4f6662 Fix deprecation of httpRoot 2021-04-26 14:43:06 +01:00
Kazuhito Yokoi
46af2e37a7 Add Japanese translations for delay node enhancements (#2958) 2021-04-26 09:57:11 +01:00
Nick O'Leary
62f2a552ea Merge pull request #2953 from node-red/depreacte-usage-of-httpRoot-and-add-warning
Deprecate usage of httpRoot and add warning
2021-04-23 16:42:01 +01:00
Dave Conway-Jones
b053e02174 remove httpRoot from setting.js entirely 2021-04-23 16:38:45 +01:00
Dave Conway-Jones
3798167908 Update packages/node_modules/@node-red/runtime/locales/en-US/runtime.json
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2021-04-23 16:36:22 +01:00
Dave Conway-Jones
56fe2014e1 Update packages/node_modules/@node-red/runtime/lib/index.js
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2021-04-23 16:36:15 +01:00
Nick O'Leary
be2e64433f Merge pull request #2951 from node-red/fix-flowfile-name-in-settings
fix flowfile name to flows.json in settings
2021-04-23 16:27:45 +01:00
Dave Conway-Jones
8732e89e55 Update packages/node_modules/@node-red/runtime/locales/en-US/runtime.json
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2021-04-23 16:22:50 +01:00
Dave Conway-Jones
fdd0a93bad Deprecate use of httpRoot in settings and add warning
(no change is actual behaviour yet - just warning)
Should we remove option from settings ? or just label it ?
2021-04-23 15:42:57 +01:00
Nick O'Leary
dd12572b1d Allow node16 build to fail for now 2021-04-23 14:30:50 +01:00
Nick O'Leary
e23f20227a Initial migration from request to got for http-request node 2021-04-23 14:19:15 +01:00
Dave Conway-Jones
5cc791690b fix flowfile name to flows.json in settings
and warn if not set (as if anyone reads warnings)
Move setting to top of settings.js as it will be edited more often.
Default behaviour will still work
(needs translations)
2021-04-23 14:09:06 +01:00
Dave Conway-Jones
93971537b4 add rate option to queue and timed modes. so a simple check box instead. 2021-04-22 11:02:34 +01:00
Dave Conway-Jones
87e816a7f5 Delay node - Make msg.rate an optional override 2021-04-22 10:26:35 +01:00
Dave Conway-Jones
0f45b1da48 Try to make delay modes consistent as regards flush
behaviour is different. May cause minor breakage.
if flush arrives with payload that is now included with the flushed data so no data is lost. Previously any payload was dropped.
2021-04-22 09:43:54 +01:00
Kazuhito Yokoi
a20049c82a Delay node enhancements (#2294)
* Remove unused messages in message catalog

* Support msg.rate in delay node

* Support nodeMessageBufferMaxLength in delay node

* Add logging function for queue size

* Support msg.nodeMessageBufferMaxLength

* Revert "Support msg.nodeMessageBufferMaxLength"

This reverts commit cc72f892f7.

* Improve logging function for delay node

* Add support for Messaging API to delay node

* Add documentation about msg.rate in delay node

* Add test cases for msg.rate in delay node

Co-authored-by: Dave Conway-Jones <dceejay@users.noreply.github.com>
2021-04-22 09:01:28 +01:00
Nick O'Leary
250005ad16 Allow npm install args to be customised by preInstall trigger 2021-04-20 22:55:06 +01:00
Nick O'Leary
719aea2a58 Add Node 16 to travis 2021-04-20 18:38:35 +01:00
Nick O'Leary
68fef169f3 Merge pull request #2944 from node-red/Pull-in-RBE-and-push-out-tail
v2: Pull in RBE node and push out tail
2021-04-20 10:57:37 +01:00
Nick O'Leary
c668201df4 Merge pull request #2931 from node-red/join-default
Join: change default manual mode to object
2021-04-20 10:57:23 +01:00
Nick O'Leary
1d68c8cc87 Merge pull request #2940 from node-red/i18n-update
Update to latest i18n in editor and runtime
2021-04-20 10:57:08 +01:00
Nick O'Leary
b9ac8b42ea Use paletteLabel if set in help sidebar 2021-04-19 21:07:44 +01:00
Nick O'Leary
b4a03a56b4 Allow preInstall hook to return false to skip npm install 2021-04-19 20:29:30 +01:00
Dave Conway-Jones
e0c7269b8e bump other refs to bcrypt up to 5.0.1 2021-04-19 13:21:12 +01:00
Dave Conway-Jones
73063df11b Pull in RBE node and push out tail 2021-04-19 13:09:13 +01:00
Nick O'Leary
f8855b83fa Update i18next in util package 2021-04-16 17:11:57 +01:00
Nick O'Leary
0d0459d83d Update to latest i18n in editor and runtime
Fixes #2924
2021-04-16 16:52:12 +01:00
Nick O'Leary
d2432716ea Fix hook requires in unit tests 2021-04-15 15:30:02 +01:00
Nick O'Leary
52ef85cba3 Update test for latest sinon 2021-04-15 15:15:52 +01:00
Nick O'Leary
8140057bea Add pre/postInstall hooks to module install path 2021-04-15 15:12:40 +01:00
Nick O'Leary
22df59e229 Update hooks api to support promise api 2021-04-15 15:12:35 +01:00
Nick O'Leary
ed351eee54 Move hooks to util package 2021-04-15 15:12:30 +01:00
Nick O'Leary
c021b4c368 Merge pull request #2922 from node-red/update-dependencies
Update dependencies
2021-04-15 14:57:07 +01:00
Nick O'Leary
aac2a8f830 File node: Add fileWorkingDirectory to customise how relative paths are resolved 2021-04-12 18:00:58 +01:00
Nick O'Leary
8269490dd1 Join: change default manual mode to object 2021-04-12 14:22:27 +01:00
Nick O'Leary
82ced56bed Update package versions 2021-04-09 14:12:10 +01:00
Nick O'Leary
982b8ea51d Update fs-extra and semver 2021-04-09 13:53:06 +01:00
Nick O'Leary
877c463494 Update to latest sinon 2021-04-09 11:22:57 +01:00
Nick O'Leary
9882582903 Update to latest bcrypt 2021-04-09 10:50:35 +01:00
Nick O'Leary
ba566657f1 Set minimum node version to 12 2021-04-09 10:37:05 +01:00
Nick O'Leary
cb1a178fbf Set 2.0.0-beta.1 version 2021-04-09 10:35:19 +01:00
276 changed files with 39224 additions and 1909 deletions

View File

@@ -1,4 +1,4 @@
name: PublishDockerImage
name: Publish Release
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
on:

30
.github/workflows/tests.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Run tests
on:
push:
branches: [ master, dev ]
pull_request:
branches: [ master, dev ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12, 14, 16]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: npm install
- name: Run tests
run: |
npm run test
- name: Publish to coveralls.io
if: ${{ matrix.node-version == 14 }}
uses: coverallsapp/github-action@v1.1.2
with:
github-token: ${{ github.token }}

View File

@@ -1,21 +0,0 @@
sudo: false
addons:
chrome: stable
language: node_js
matrix:
include:
- node_js: "14"
script:
- ./node_modules/.bin/grunt && ( cat coverage/lcov.info | $(npm get prefix)/bin/coveralls || true ) && rm -rf coverage
# - scripts/install-ui-test-dependencies.sh && grunt test-ui
before_script:
- npm install -g coveralls
- node_js: "12"
script:
- ./node_modules/.bin/grunt no-coverage
- node_js: "10"
script:
- ./node_modules/.bin/grunt no-coverage
#- node_js: "8"
# script:
# - ./node_modules/.bin/grunt no-coverage

14
API.md
View File

@@ -1,8 +1,12 @@
Node-RED Modules
---
Node-RED consists of 6 node modules under the `@node-red` scope, which are pulled together
by the top-level `node-red` module. The typical scenario is where you are embedding Node-RED into your
own application, in which case you would use the `node-red` module rather than any of the
internal modules directly.
```javascript
let RED = require("node-red");
```
Node-RED provides a set of node modules that implement different parts of the
application.
Module | Description
-------|-------
@@ -11,5 +15,5 @@ Module | Description
[@node-red/runtime](@node-red_runtime.html) | the core runtime of Node-RED
[@node-red/util](@node-red_util.html) | common utilities for the Node-RED runtime and editor modules
[@node-red/registry](@node-red_registry.html) | the internal node registry
@node-red/nodes | the default set of core nodes
@node-red/nodes | the default set of core nodes. This module only contains the Node-RED nodes - it does not expose any APIs.
@node-red/editor-client | the client-side resources of the Node-RED editor application

View File

@@ -1,3 +1,149 @@
#### 2.0.0-beta.2: Beta Release
**See 2.0.0-beta.1 for migration notes**
Runtime
- Add `node-red admin init` (via `node-red-admin@2.1.0`)
- Move to GH Actions rather than Travis for build (#3042) @knolleary
Editor
- Include hasUser=false config nodes when exporting whole flow (#3048)
- Emit nodes:change for any updated config node when node deleted/added
- Fix padding of compact notification Closes #3045
- Ensure any html in changelog is escaped before displaying
- Add support for Map/Set property types on Debug (#3040) @knolleary
- Add 'theme' to default settings file
- Add RED.view.annotations api (#3032) @knolleary
- Update monaco editor to V0.25.2 (#3031) @Steve-Mcl
- Lower tray zIndex when overlay tray being opened Fixes #3019
- Reduce z-Index of Function expand buttons to prevent overlap Part of #3019
- Ensure RED.clipboard.import displays the right library Fixes #3021
- Batch messages sent over comms to prevent flooding (#3025) @knolleary
- Allow RED.popover.panel to specify a closeButton to ignore click events on
- Use browser default language for initial page load
- Add css var for node font color
- Fix label padding of toggleButton
- Give sidebar open tab a bit more room for its label
- Various Monaco updates (#3015) @Steve-Mcl
- Log readOnly on startup (#3024) @sammachin
- Translation updates (#3020 #3022) @HiroyasuNishiyama @kazuhitoyokoi
Nodes
- HTTP Request: Fix proxy handling (#3044) @hardillb
- HTTP Request: Handle basic auth with @ in username (#3017) @hardillb
- Add Japanese translation for file-in node (#3037 #3039) @kazuhitoyokoi
- File In: Add option for file-in node to include all properties (default off) (#3035) @dceejay
- Exec: add windowsHide option to hide windows under Windows (#3026) @natcl
- Support loading external module sub path Fixes #3023
#### 2.0.0-beta.1: Beta Release
Migration from 1.x
- Node-RED now requires Node.js 12.x or later.
- The following nodes have had significant dependency updates. Unless stated,
they should be fully backward compatible.
- RBE: Relabelled as 'filter' to make it more discoverable and made part of
the core palette, rather than as a separate module.
- Tail: This node has been removed from the default palette. You can reinstall it
from node-red-node-tail
- HTTP Request: Reimplemented with a different underlying module. We have
tried to maintain 100% functional compatibility, but it is possible
some edge cases remain. In particular, if you are using http proxies in
your environment.
- JSON: The schema validation option no longer supports JSON-Schema draft-04
- HTML: Its underlying module has had a major version update. Should be fully
backward compatible.
Runtime
- [MAJOR] Set minimum node version to 12.
- [MAJOR] Fix flowfile name to flows.json in settings (#2951) @dceejay
- [MAJOR] Update to latest i18n in editor and runtime (#2940) @knolleary
- [MAJOR] Deprecate usage of httpRoot (#2953) @knolleary
- Add pre/postInstall hooks to npm install handling (#2936) @knolleary
- Add engine-strict flag to npm install args (#2965) @nileio
- Restructure default settings.js to be more organised (#3012) @knolleary
- Ensure httpServerOptions gets applied to ALL the express apps
- Allow RED.settings.set to replace string property with object property
- Update debug tests to handle compact comms format
- Updates to encode/decode message when passed over debug comms link
- Remove all input event listeners on a node once it is closed
- Move hooks to util package
- Rework hooks structure to be a linkedlist
- Update dependencies (#2922) @knolleary
Editor
- [MAJOR] Change node id generation to give fixed length values without '.' (#2987) @knolleary
- [MAJOR] Add Monaco code editor (#2971) @Steve-Mcl
- Update to latest Monaco (#3007) @Steve-Mcl
- Update Node-RED Function typings in Monaco (#3008) @Steve-Mcl
- Add css named variables for certain key colours (#2994) @knolleary
- Improve contrast of export dialog JSON font color
- Switch editableList buttons from <a> to <button> elements
- Add option to RED.nodes.createCompleteNodeSet to include node dimensions
- Fix css of node help table of contents elements
- Improve red-ui-node-icon css and add red-ui-node-icon-small modifier class
- Add RED.hooks to editor
- Add viewAddPort viewRemovePort viewAddNode viewRemoveNode hooks to view
- Use paletteLabel if set in help sidebar
- Add missing args from JSONata $now signature
Nodes
- [MAJOR] Relabel RBE node as 'filter' and move into core. Also remove tail (#2944) @dceejay
- [MAJOR] HTTP Request: migrate to 'got' module (#2952) @knolleary
- [MAJOR] Move Inject node to CronosJS module (#2959) @knolleary
- [MAJOR] JSON: Update ajv to 8.2.0 - drop support for JSON-Schema draft-04 (#2969) @knolleary
- [MAJOR] HTML node: cheerio update to 1.x (#3011) @knolleary
- Join: change default manual mode to object (#2931) @knolleary
- File node: Add fileWorkingDirectory (#2932) @knolleary
- Delay node enhancements (#2294) @kazuhitoyokoi (#2949) @dceejay
- Add Japanese translations for delay node enhancements (#2958) @kazuhitoyokoi
- Inject node: reorder TypedInput options (#2961) @dceejay
- HTTP Request: update to work with proxies (#2983) @hardillb (#3009) @hardillb
- HTTP Request: fix msg.responseUrl (#2986) @hardillb
- TLS: Add ALPN support to TLS node (#2988) @hardillb
- Inject: add "Inject now" button to edit dialog (#2990) @Steve-Mcl
### 1.3.5 Maintenance Release
Editor
- Open subflow tab next to active tab rather than at the end
- Shrink default notification box
- Support mousewheel scroll in tab bar
- Revert some of #2967 to fix treeList gutter width calculation
- Prevent unknown node from breaking editor
- Stop module with missing types from preventing editor load
- Handle sidebar tab that no longer exists when setting first active
- Fix plugin loading when browser sends unrecognised lang
- Prevent error whilst drag/drop importing from leaving dropTarget visible Fixes #2982
- Fix scaling issues when dragging nodes into scaled workspace
- Fix incorrect shortcut keys in info tips (#2980) @kazuhitoyokoi
- Reduce code duplication around node/label generation
- Fix theme handling when no editorTheme.page setting
- Fix jshint error in treeList
Runtime
- Fix error handling in runtime/lib/api/nodes
- Add Node 16 with sass fixed
- Migrate from node-sass to sass (#2984)
- Fix "installRetry" was declared a constant and changed (#2974) @aheissenberger
Nodes
- Function: Fix 'SyntaxError' in Function node when last line of on-stop is a comment
- Function: Fix Function tab label names in the node help text Closes #2978
- Function: Update Japanese info text of function node (#2985) @HiroyasuNishiyama
### 1.3.4 Maintenance Release
Editor

View File

@@ -16,7 +16,7 @@
var path = require("path");
var fs = require("fs-extra");
var sass = require("node-sass");
var sass = require("sass");
module.exports = function(grunt) {
@@ -40,11 +40,10 @@ module.exports = function(grunt) {
if (nonHeadless) {
process.env.NODE_RED_NON_HEADLESS = true;
}
let packageFile = grunt.file.readJSON('package.json')
process.env.NODE_RED_PACKAGE_VERSION = packageFile.version;
const pkg = grunt.file.readJSON('package.json');
process.env.NODE_RED_PACKAGE_VERSION = pkg.version;
grunt.initConfig({
pkg: packageFile,
pkg: pkg,
paths: {
dist: ".dist"
},
@@ -138,6 +137,7 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js",
"packages/node_modules/@node-red/editor-client/src/js/red.js",
"packages/node_modules/@node-red/editor-client/src/js/events.js",
"packages/node_modules/@node-red/editor-client/src/js/hooks.js",
"packages/node_modules/@node-red/editor-client/src/js/i18n.js",
"packages/node_modules/@node-red/editor-client/src/js/settings.js",
"packages/node_modules/@node-red/editor-client/src/js/user.js",
@@ -170,6 +170,7 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/statusBar.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/view.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/view-annotations.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js",
@@ -182,6 +183,7 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/editor.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/*.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/*.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/tray.js",
"packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js",
@@ -211,7 +213,9 @@ module.exports = function(grunt) {
"node_modules/marked/marked.min.js",
"node_modules/dompurify/dist/purify.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/i18next/i18next.min.js",
"node_modules/i18next/i18next.min.js",
"node_modules/i18next-http-backend/i18nextHttpBackend.min.js",
"node_modules/jquery-i18next/jquery-i18next.min.js",
"node_modules/jsonata/jsonata-es5.min.js",
"packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js",
"packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js",
@@ -284,7 +288,9 @@ module.exports = function(grunt) {
"packages/node_modules/@node-red/editor-client/public/index.html",
"packages/node_modules/@node-red/editor-client/public/favicon.ico",
"packages/node_modules/@node-red/editor-client/public/icons",
"packages/node_modules/@node-red/editor-client/public/vendor"
"packages/node_modules/@node-red/editor-client/public/vendor",
"packages/node_modules/@node-red/editor-client/public/types/node",
"packages/node_modules/@node-red/editor-client/public/types/node-red",
]
},
release: {
@@ -374,11 +380,24 @@ module.exports = function(grunt) {
src: [
'ace/**',
'jquery/css/base/**',
'font-awesome/**'
'font-awesome/**',
'monaco/dist/**',
'monaco/types/extraLibs.js',
'monaco/style.css',
'monaco/monaco-bootstrap.js'
],
expand: true,
dest: 'packages/node_modules/@node-red/editor-client/public/vendor/'
},
{
cwd: 'packages/node_modules/@node-red/editor-client/src',
src: [
'types/node/*.ts',
'types/node-red/*.ts',
],
expand: true,
dest: 'packages/node_modules/@node-red/editor-client/public/'
},
{
cwd: 'packages/node_modules/@node-red/editor-client/src/icons',
src: '**',

View File

@@ -1,6 +1,6 @@
{
"name": "node-red",
"version": "1.3.4",
"version": "2.0.0-beta.2",
"description": "Low-code programming for event-driven applications",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
@@ -26,29 +26,34 @@
}
],
"dependencies": {
"ajv": "6.12.6",
"acorn": "8.4.1",
"acorn-walk": "8.1.1",
"ajv": "8.6.0",
"async-mutex": "0.3.1",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"body-parser": "1.19.0",
"cheerio": "0.22.0",
"cheerio": "1.0.0-rc.10",
"clone": "2.1.2",
"content-type": "1.0.4",
"cookie": "0.4.1",
"cookie-parser": "1.4.5",
"cors": "2.8.5",
"cron": "1.7.2",
"cronosjs": "1.7.1",
"denque": "1.5.0",
"express": "4.17.1",
"express-session": "1.17.1",
"fs-extra": "8.1.0",
"express-session": "1.17.2",
"form-data": "4.0.0",
"fs-extra": "10.0.0",
"fs.notify": "0.0.4",
"got": "11.8.2",
"hash-sum": "2.0.0",
"hpagent": "^0.1.2",
"https-proxy-agent": "5.0.0",
"i18next": "15.1.2",
"iconv-lite": "0.6.2",
"i18next": "20.3.2",
"iconv-lite": "0.6.3",
"is-utf8": "0.2.1",
"js-yaml": "3.14.0",
"js-yaml": "3.14.1",
"json-stringify-safe": "5.0.1",
"jsonata": "1.8.4",
"lodash.clonedeep": "^4.5.0",
@@ -56,13 +61,10 @@
"memorystore": "1.6.6",
"mime": "2.5.2",
"moment-timezone": "0.5.33",
"mqtt": "4.2.6",
"mqtt": "4.2.8",
"multer": "1.4.2",
"mustache": "4.2.0",
"node-red-admin": "^0.2.6",
"node-red-node-rbe": "^0.5.0",
"node-red-node-sentiment": "^0.1.6",
"node-red-node-tail": "^0.3.0",
"node-red-admin": "^2.1.0",
"nopt": "5.0.0",
"oauth2orize": "1.11.0",
"on-headers": "1.0.2",
@@ -70,51 +72,54 @@
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"raw-body": "2.4.1",
"request": "2.88.0",
"semver": "6.3.0",
"semver": "7.3.5",
"tar": "6.1.0",
"uglify-js": "3.13.3",
"ws": "6.2.1",
"tough-cookie": "4.0.0",
"uglify-js": "3.13.10",
"uuid": "8.3.2",
"ws": "7.5.1",
"xml2js": "0.4.23"
},
"optionalDependencies": {
"bcrypt": "3.0.8"
"bcrypt": "5.0.1"
},
"devDependencies": {
"dompurify": "2.2.7",
"grunt": "1.3.0",
"dompurify": "2.2.9",
"grunt": "1.4.1",
"grunt-chmod": "~1.1.1",
"grunt-cli": "~1.4.2",
"grunt-cli": "~1.4.3",
"grunt-concurrent": "3.0.0",
"grunt-contrib-clean": "~2.0.0",
"grunt-contrib-compress": "1.6.0",
"grunt-contrib-compress": "2.0.0",
"grunt-contrib-concat": "~1.0.1",
"grunt-contrib-copy": "~1.0.0",
"grunt-contrib-jshint": "~2.1.0",
"grunt-contrib-uglify": "~4.0.1",
"grunt-contrib-jshint": "3.0.0",
"grunt-contrib-uglify": "5.0.1",
"grunt-contrib-watch": "~1.1.0",
"grunt-jsdoc": "2.4.1",
"grunt-jsdoc-to-markdown": "5.0.0",
"grunt-jsdoc-to-markdown": "6.0.0",
"grunt-jsonlint": "2.1.3",
"grunt-mkdir": "~1.1.0",
"grunt-npm-command": "~0.1.2",
"grunt-sass": "~3.1.0",
"grunt-simple-mocha": "~0.4.1",
"grunt-simple-nyc": "^3.0.1",
"http-proxy": "1.18.1",
"i18next-http-backend": "1.2.6",
"jquery-i18next": "1.2.1",
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
"marked": "2.0.1",
"marked": "2.1.3",
"minami": "1.2.3",
"mocha": "^5.2.0",
"mocha": "9.0.1",
"node-red-node-test-helper": "^0.2.7",
"node-sass": "^5.0.0",
"nodemon": "2.0.7",
"nodemon": "2.0.8",
"proxy": "^1.0.2",
"sass": "1.35.1",
"should": "13.2.3",
"sinon": "1.17.7",
"sinon": "11.1.1",
"stoppable": "^1.1.0",
"supertest": "5.0.0"
"supertest": "6.1.3"
},
"engines": {
"node": ">=8"
"node": ">=12"
}
}

View File

@@ -39,6 +39,15 @@ module.exports = {
var adminApp = express();
var defaultServerSettings = {
"x-powered-by": false
}
var serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{});
for (var eOption in serverSettings) {
adminApp.set(eOption, serverSettings[eOption]);
}
// Flows
adminApp.get("/flows",needsPermission("flows.read"),flows.get,apiUtil.errorHandler);
adminApp.post("/flows",needsPermission("flows.write"),flows.post,apiUtil.errorHandler);

View File

@@ -17,9 +17,8 @@ module.exports = {
})
} else {
opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages());
if (/[^a-z\-\*]/i.test(opts.lang)) {
res.json({});
return;
if (/[^0-9a-z=\-\*]/i.test(opts.lang)) {
opts.lang = "en-US";
}
runtimeAPI.plugins.getPluginConfigs(opts).then(function(configs) {
res.send(configs);
@@ -32,9 +31,8 @@ module.exports = {
lang: req.query.lng,
req: apiUtils.getRequestLogObject(req)
}
if (/[^a-z\-\*]/i.test(opts.lang)) {
res.json({});
return;
if (/[^0-9a-z=\-\*]/i.test(opts.lang)) {
opts.lang = "en-US";
}
runtimeAPI.plugins.getPluginCatalogs(opts).then(function(result) {
res.json(result);

View File

@@ -158,25 +158,31 @@ function CommsConnection(ws, user) {
}
CommsConnection.prototype.send = function(topic,data) {
var self = this;
if (topic && data) {
this.stack.push({topic:topic,data:data});
}
this._queueSend();
}
CommsConnection.prototype._queueSend = function() {
var self = this;
if (!this._xmitTimer) {
this._xmitTimer = setTimeout(function() {
try {
self.ws.send(JSON.stringify(self.stack));
self.ws.send(JSON.stringify(self.stack.splice(0,50)));
self.lastSentTime = Date.now();
} catch(err) {
removeActiveConnection(self);
log.warn(log._("comms.error-send",{message:err.toString()}));
}
delete self._xmitTimer;
self.stack = [];
if (self.stack.length > 0) {
self._queueSend();
}
},50);
}
}
CommsConnection.prototype.subscribe = function(topic) {
runtimeAPI.comms.subscribe({
user: this.user,

View File

@@ -64,10 +64,12 @@ module.exports = {
}
});
}
if (settings.httpServerOptions) {
for (var eOption in settings.httpServerOptions) {
editorApp.set(eOption, settings.httpServerOptions[eOption]);
}
var defaultServerSettings = {
"x-powered-by": false
}
var serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{});
for (var eOption in serverSettings) {
editorApp.set(eOption, serverSettings[eOption]);
}
editorApp.get("/",ensureRuntimeStarted,ui.ensureSlash,ui.editor);

View File

@@ -33,7 +33,7 @@ var defaultContext = {
asset: {
red: (process.env.NODE_ENV == "development")? "red/red.js":"red/red.min.js",
main: (process.env.NODE_ENV == "development")? "red/main.js":"red/main.min.js",
vendorMonaco: ""
}
};
@@ -93,6 +93,7 @@ module.exports = {
themeContext = clone(defaultContext);
themeSettings = null;
theme = settings.editorTheme || {};
themeContext.asset.vendorMonaco = ((theme.codeEditor || {}).lib === "monaco") ? "vendor/monaco/monaco-bootstrap.js" : "";
activeTheme = theme.theme;
},
@@ -231,6 +232,7 @@ module.exports = {
themePlugin.path
);
themeContext.page.css = cssFiles.concat(themeContext.page.css || [])
theme.page = theme.page || {_:{}}
theme.page._.css = cssFiles.concat(theme.page._.css || [])
}
if (themePlugin.scripts) {
@@ -241,6 +243,7 @@ module.exports = {
themePlugin.path
)
themeContext.page.scripts = scriptFiles.concat(themeContext.page.scripts || [])
theme.page = theme.page || {_:{}}
theme.page._.scripts = cssFiles.concat(theme.page._.scripts || [])
}
}

View File

@@ -64,6 +64,14 @@ function init(settings,_server,storage,runtimeAPI) {
}
}
var defaultServerSettings = {
"x-powered-by": false
}
var serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{});
for (var eOption in serverSettings) {
adminApp.set(eOption, serverSettings[eOption]);
}
auth.init(settings,storage);
var maxApiRequestSize = settings.apiMaxLength || '5mb';

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-api",
"version": "1.3.4",
"version": "2.0.0-beta.2",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,13 +16,13 @@
}
],
"dependencies": {
"@node-red/util": "1.3.4",
"@node-red/editor-client": "1.3.4",
"@node-red/util": "2.0.0-beta.2",
"@node-red/editor-client": "2.0.0-beta.2",
"bcryptjs": "2.4.3",
"body-parser": "1.19.0",
"clone": "2.1.2",
"cors": "2.8.5",
"express-session": "1.17.1",
"express-session": "1.17.2",
"express": "4.17.1",
"memorystore": "1.6.6",
"mime": "2.5.2",
@@ -32,9 +32,9 @@
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"passport": "0.4.1",
"ws": "6.2.1"
"ws": "7.5.1"
},
"optionalDependencies": {
"bcrypt": "3.0.6"
"bcrypt": "5.0.1"
}
}

View File

@@ -111,6 +111,7 @@
"projects-open": "Open",
"projects-settings": "Project Settings",
"showNodeLabelDefault": "Show label of newly added nodes",
"codeEditor": "Code Editor",
"groups": "Groups",
"groupSelection": "Group selection",
"ungroupSelection": "Ungroup selection",
@@ -885,6 +886,9 @@
"eval": "Error evaluating expression:\n __message__"
}
},
"monaco": {
"setTheme": "Set theme"
},
"jsEditor": {
"title": "JavaScript editor"
},

View File

@@ -52,8 +52,8 @@
"desc": "Finds occurrences of `pattern` within `str` and replaces them with `replacement`.\n\nThe optional `limit` parameter is the maximum number of replacements."
},
"$now": {
"args":"",
"desc":"Generates a timestamp in ISO 8601 compatible format and returns it as a string."
"args":"$[picture [, timezone]]",
"desc":"Generates a timestamp in ISO 8601 compatible format and returns it as a string. If the optional picture and timezone parameters are supplied, then the current timestamp is formatted as described by the `$fromMillis()` function"
},
"$base64encode": {
"args":"string",
@@ -200,8 +200,8 @@
"desc": "Returns a copy of the `string` with extra padding, if necessary, so that its total number of characters is at least the absolute value of the `width` parameter.\n\nIf `width` is a positive number, then the string is padded to the right; if negative, it is padded to the left.\n\nThe optional `char` argument specifies the padding character(s) to use. If not specified, it defaults to the space character."
},
"$fromMillis": {
"args": "number",
"desc": "Convert a number representing milliseconds since the Unix Epoch (1 January, 1970 UTC) to a timestamp string in the ISO 8601 format."
"args": "number, [, picture [, timezone]]",
"desc": "Convert the `number` representing milliseconds since the Unix Epoch (1 January, 1970 UTC) to a formatted string representation of the timestamp as specified by the picture string.\n\nIf the optional `picture` parameter is omitted, then the timestamp is formatted in the ISO 8601 format.\n\nIf the optional `picture` string is supplied, then the timestamp is formatted occording to the representation specified in that string. The behaviour of this function is consistent with the two-argument version of the XPath/XQuery function `format-dateTime` as defined in the XPath F&O 3.1 specification. The picture string parameter defines how the timestamp is formatted and has the same syntax as `format-dateTime`.\n\nIf the optional `timezone` string is supplied, then the formatted timestamp will be in that timezone. The `timezone` string should be in the format '±HHMM', where ± is either the plus or minus sign and HHMM is the offset in hours and minutes from UTC. Positive offset for timezones east of UTC, negative offset for timezones west of UTC."
},
"$formatNumber": {
"args": "number, picture [, options]",

View File

@@ -111,6 +111,7 @@
"projects-open": "開く",
"projects-settings": "設定",
"showNodeLabelDefault": "追加したノードのラベルを表示",
"codeEditor": "コードエディタ",
"groups": "グループ",
"groupSelection": "選択部分をグループ化",
"ungroupSelection": "選択部分をグループ解除",
@@ -885,6 +886,9 @@
"eval": "表現評価エラー:\n __message__"
}
},
"monaco": {
"setTheme": "テーマを設定:"
},
"jsEditor": {
"title": "JavaScriptエディタ"
},

View File

@@ -52,8 +52,8 @@
"desc": "文字列 `str` からパターン `pattern` を検索し、置換文字列 `replacement` に置き換えます。\n\n任意の引数 `limit` には、置換回数の上限値を指定します。"
},
"$now": {
"args": "",
"desc": "ISO 8601互換形式の時刻を生成し、文字列として返します。"
"args": "$[picture [, timezone]]",
"desc": "ISO 8601互換形式の時刻を生成し、文字列として返します。pictureおよびtimezoneパラメータが指定されている場合、現在時刻を`$fromMillis()`関数の説明に従ってフォーマットします。"
},
"$base64encode": {
"args": "string",
@@ -200,8 +200,8 @@
"desc": "文字数が引数 `width` の絶対値以上となるよう、必要に応じて追加文字を付け足した `string` のコピーを返します。\n\n`width` が正の値の場合、文字列の右側に追加文字を付け足します。もし負の値の場合、文字列の左側に追加文字を付け足します。\n\n任意の引数 `char` には、本関数で用いる追加文字を指定します。もし追加文字を指定しない場合は、既定値として空白文字を使用します。"
},
"$fromMillis": {
"args": "number",
"desc": "Unixエポック(1 January, 1970 UTC)からの経過ミリ秒を表す数値を、ISO 8601形式のタイムスタンプの文字列に変換します。"
"args": "number, [, picture [, timezone]]",
"desc": "Unixエポック(1 January, 1970 UTC)からの経過ミリ秒を表す数値を、`picture`の指定に従ってタイムスタンプの文字列に変換します。\n\n`picture`パラメータが指定されない場合、ISO 8601形式に変換します。\n\n`picture`を指定すると、指定した文字列に従って変換を行います。この変換はXPath F&O 3.1仕様におけるXPath/XQueryの2引数形式`format-dateTime`と同様です。`picture`パラメータはタイムスタンプの変換形式を定義し、その書式は`format-dateTime`と同じです。\n\n`timezone`を指定すると、指定タイムゾーンで変換します。`timezone`は'±HHMM'という形式で指定します。ここで、±は+もしくは-記号を表し、HHMMはUTCからの差分時間と分を表します。正の差分はUTCの東、負の差分は西のタイムゾーンとなります。"
},
"$formatNumber": {
"args": "number, picture [, options]",

View File

@@ -648,7 +648,7 @@
},
"context": {
"name": "上下文数据",
"label": "上下",
"label": "上下",
"none": "未选择",
"refresh": "刷新以加载",
"empty": "空",

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-client",
"version": "1.3.4",
"version": "2.0.0-beta.2",
"license": "Apache-2.0",
"repository": {
"type": "git",

View File

@@ -66,12 +66,14 @@ RED.history = (function() {
var importedResult = RED.nodes.import(ev.config,{importMap: importMap})
inverseEv = {
t: 'replace',
config: importedResult.removedNodes
config: importedResult.removedNodes,
dirty: RED.nodes.dirty()
}
}
} else if (ev.t == 'add') {
inverseEv = {
t: "delete",
dirty: RED.nodes.dirty()
};
if (ev.nodes) {
inverseEv.nodes = [];
@@ -158,7 +160,8 @@ RED.history = (function() {
} else if (ev.t == "delete") {
inverseEv = {
t: "add"
t: "add",
dirty: RED.nodes.dirty()
};
if (ev.workspaces) {
inverseEv.workspaces = [];
@@ -300,11 +303,12 @@ RED.history = (function() {
} else if (ev.t == "move") {
inverseEv = {
t: 'move',
nodes: []
nodes: [],
dirty: RED.nodes.dirty()
};
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};
var rn = {n: n.n, ox: n.n.x, oy: n.n.y, dirty: true, moved: n.n.moved};
inverseEv.nodes.push(rn);
n.n.x = n.ox;
n.n.y = n.oy;
@@ -336,7 +340,9 @@ RED.history = (function() {
} else if (ev.t == "edit") {
inverseEv = {
t: "edit",
changes: {}
changes: {},
changed: ev.node.changed,
dirty: RED.nodes.dirty()
};
inverseEv.node = ev.node;
for (i in ev.changes) {
@@ -552,7 +558,8 @@ RED.history = (function() {
} else if (ev.t == "reorder") {
inverseEv = {
t: 'reorder',
order: RED.nodes.getWorkspaceOrder()
order: RED.nodes.getWorkspaceOrder(),
dirty: RED.nodes.dirty()
};
if (ev.order) {
RED.workspaces.order(ev.order);

View File

@@ -0,0 +1,156 @@
RED.hooks = (function() {
var VALID_HOOKS = [
]
var hooks = { }
var labelledHooks = { }
function add(hookId, callback) {
var parts = hookId.split(".");
var id = parts[0], label = parts[1];
// if (VALID_HOOKS.indexOf(id) === -1) {
// throw new Error("Invalid hook '"+id+"'");
// }
if (label && labelledHooks[label] && labelledHooks[label][id]) {
throw new Error("Hook "+hookId+" already registered")
}
var hookItem = {cb:callback, previousHook: null, nextHook: null }
var tailItem = hooks[id];
if (tailItem === undefined) {
hooks[id] = hookItem;
} else {
while(tailItem.nextHook !== null) {
tailItem = tailItem.nextHook
}
tailItem.nextHook = hookItem;
hookItem.previousHook = tailItem;
}
if (label) {
labelledHooks[label] = labelledHooks[label]||{};
labelledHooks[label][id] = hookItem;
}
}
function remove(hookId) {
var parts = hookId.split(".");
var id = parts[0], label = parts[1];
if ( !label) {
throw new Error("Cannot remove hook without label: "+hookId)
}
if (labelledHooks[label]) {
if (id === "*") {
// Remove all hooks for this label
var hookList = Object.keys(labelledHooks[label]);
for (var i=0;i<hookList.length;i++) {
removeHook(hookList[i],labelledHooks[label][hookList[i]])
}
delete labelledHooks[label];
} else if (labelledHooks[label][id]) {
removeHook(id,labelledHooks[label][id])
delete labelledHooks[label][id];
if (Object.keys(labelledHooks[label]).length === 0){
delete labelledHooks[label];
}
}
}
}
function removeHook(id,hookItem) {
var previousHook = hookItem.previousHook;
var nextHook = hookItem.nextHook;
if (previousHook) {
previousHook.nextHook = nextHook;
} else {
hooks[id] = nextHook;
}
if (nextHook) {
nextHook.previousHook = previousHook;
}
hookItem.removed = true;
if (!previousHook && !nextHook) {
delete hooks[id];
}
}
function trigger(hookId, payload, done) {
var hookItem = hooks[hookId];
if (!hookItem) {
if (done) {
done();
}
return;
}
function callNextHook(err) {
if (!hookItem || err) {
if (done) { done(err) }
return err;
}
if (hookItem.removed) {
hookItem = hookItem.nextHook;
return callNextHook();
}
var callback = hookItem.cb;
if (callback.length === 1) {
try {
let result = callback(payload);
if (result === false) {
// Halting the flow
if (done) { done(false) }
return result;
}
hookItem = hookItem.nextHook;
return callNextHook();
} catch(e) {
console.warn(e);
if (done) { done(e);}
return e;
}
} else {
// There is a done callback
try {
callback(payload,function(result) {
if (result === undefined) {
hookItem = hookItem.nextHook;
callNextHook();
} else {
if (done) { done(result)}
}
})
} catch(e) {
console.warn(e);
if (done) { done(e) }
return e;
}
}
}
return callNextHook();
}
function clear() {
hooks = {}
labelledHooks = {}
}
function has(hookId) {
var parts = hookId.split(".");
var id = parts[0], label = parts[1];
if (label) {
return !!(labelledHooks[label] && labelledHooks[label][id])
}
return !!hooks[id]
}
return {
has: has,
clear: clear,
add: add,
remove: remove,
trigger: trigger
}
})();

View File

@@ -18,53 +18,66 @@ RED.i18n = (function() {
var apiRootUrl;
function detectLanguage() {
return navigator.language
}
return {
init: function(options, done) {
apiRootUrl = options.apiRootUrl||"";
var preferredLanguage = localStorage.getItem("editor-language");
var preferredLanguage = localStorage.getItem("editor-language") || detectLanguage();
var opts = {
resGetPath: apiRootUrl+'locales/__ns__?lng=__lng__',
dynamicLoad: false,
load:'current',
ns: {
namespaces: ["editor","node-red","jsonata","infotips"],
defaultNs: "editor"
backend: {
loadPath: apiRootUrl+'locales/__ns__?lng=__lng__',
},
lng: 'en-US',
// debug: true,
preload:['en-US'],
ns: ["editor","node-red","jsonata","infotips"],
defaultNS: "editor",
fallbackLng: ['en-US'],
useCookie: false,
returnObjectTrees: true
returnObjects: true,
interpolation: {
unescapeSuffix: 'HTML',
escapeValue: false,
prefix: '__',
suffix: '__'
}
};
if (preferredLanguage) {
opts.lng = preferredLanguage;
}
i18n.init(opts,function() {
i18next.use(i18nextHttpBackend).init(opts,function() {
done();
});
jqueryI18next.init(i18next, $, { handleName: 'i18n' });
RED["_"] = function() {
var v = i18n.t.apply(null,arguments);
var v = i18next.t.apply(i18next,arguments);
if (typeof v === 'string') {
return v;
} else {
return arguments[0];
}
}
},
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 preferredLangs = [localStorage.getItem("editor-language")|| detectLanguage()].concat(i18next.languages);
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'
return 'en-US'
},
loadNodeCatalog: function(namespace,done) {
var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
var languageList = [localStorage.getItem("editor-language")|| detectLanguage()].concat(i18next.languages);
var toLoad = languageList.length;
languageList.forEach(function(lang) {
$.ajax({
@@ -74,7 +87,7 @@ RED.i18n = (function() {
cache: false,
url: apiRootUrl+'nodes/'+namespace+'/messages?lng='+lang,
success: function(data) {
i18n.addResourceBundle(lang,namespace,data);
i18next.addResourceBundle(lang,namespace,data);
toLoad--;
if (toLoad === 0) {
done();
@@ -86,7 +99,7 @@ RED.i18n = (function() {
},
loadNodeCatalogs: function(done) {
var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
var languageList = [localStorage.getItem("editor-language")|| detectLanguage()].concat(i18next.languages);
var toLoad = languageList.length;
languageList.forEach(function(lang) {
@@ -99,7 +112,7 @@ RED.i18n = (function() {
success: function(data) {
var namespaces = Object.keys(data);
namespaces.forEach(function(ns) {
i18n.addResourceBundle(lang,ns,data[ns]);
i18next.addResourceBundle(lang,ns,data[ns]);
});
toLoad--;
if (toLoad === 0) {
@@ -111,7 +124,7 @@ RED.i18n = (function() {
},
loadPluginCatalogs: function(done) {
var languageList = i18n.functions.toLanguages(localStorage.getItem("editor-language")||i18n.detectLanguage());
var languageList = [localStorage.getItem("editor-language")|| detectLanguage()].concat(i18next.languages);
var toLoad = languageList.length;
languageList.forEach(function(lang) {
@@ -124,7 +137,7 @@ RED.i18n = (function() {
success: function(data) {
var namespaces = Object.keys(data);
namespaces.forEach(function(ns) {
i18n.addResourceBundle(lang,ns,data[ns]);
i18next.addResourceBundle(lang,ns,data[ns]);
});
toLoad--;
if (toLoad === 0) {
@@ -133,6 +146,7 @@ RED.i18n = (function() {
}
});
})
}
},
detectLanguage: detectLanguage
}
})();

View File

@@ -86,6 +86,10 @@ RED.nodes = (function() {
}
},
addNodeSet: function(ns) {
if (!ns.types) {
// A node has been loaded without any types. Ignore it.
return;
}
ns.added = false;
nodeSets[ns.id] = ns;
for (var j=0;j<ns.types.length;j++) {
@@ -206,8 +210,11 @@ RED.nodes = (function() {
})();
function getID() {
// return Math.floor(Math.random()*15728640 + 1048576).toString(16)
return (1+Math.random()*4294967295).toString(16);
var bytes = [];
for (var i=0;i<8;i++) {
bytes.push(Math.round(0xff*Math.random()).toString(16).padStart(2,'0'));
}
return bytes.join("");
}
function parseNodePropertyTypeString(typeString) {
@@ -363,6 +370,7 @@ RED.nodes = (function() {
} else {
var users = configNode.users;
users.splice(users.indexOf(node),1);
RED.events.emit('nodes:change',configNode)
}
}
}
@@ -687,11 +695,23 @@ RED.nodes = (function() {
/**
* Converts a node to an exportable JSON Object
**/
function convertNode(n, exportCreds) {
function convertNode(n, opts) {
var exportCreds = true;
var exportDimensions = false;
if (opts === false) {
exportCreds = false;
} else if (typeof opts === "object") {
if (opts.hasOwnProperty("credentials")) {
exportCreds = opts.credentials;
}
if (opts.hasOwnProperty("dimensions")) {
exportDimensions = opts.dimensions;
}
}
if (n.type === 'tab') {
return convertWorkspace(n);
}
exportCreds = exportCreds || false;
var node = {};
node.id = n.id;
node.type = n.type;
@@ -764,6 +784,19 @@ RED.nodes = (function() {
if (n._def.category != "config") {
node.x = n.x;
node.y = n.y;
if (exportDimensions) {
if (!n.hasOwnProperty('w')) {
// This node has not yet been drawn in the view. So we need
// to explicitly calculate its dimensions. Store the result
// on the node as if it had been drawn will save us doing
// it again
var dimensions = RED.view.calculateNodeDimensions(n);
n.w = dimensions[0];
n.h = dimensions[1];
}
node.w = n.w;
node.h = n.h;
}
node.wires = [];
for(var i=0;i<n.outputs;i++) {
node.wires.push([]);
@@ -803,7 +836,21 @@ RED.nodes = (function() {
return node;
}
function convertSubflow(n, exportCreds) {
function convertSubflow(n, opts) {
var exportCreds = true;
var exportDimensions = false;
if (opts === false) {
exportCreds = false;
} else if (typeof opts === "object") {
if (opts.hasOwnProperty("credentials")) {
exportCreds = opts.credentials;
}
if (opts.hasOwnProperty("dimensions")) {
exportDimensions = opts.dimensions;
}
}
var node = {};
node.id = n.id;
node.type = n.type;
@@ -975,11 +1022,10 @@ RED.nodes = (function() {
return nns;
}
//TODO: rename this (createCompleteNodeSet)
function createCompleteNodeSet(exportCredentials) {
if (exportCredentials === undefined) {
exportCredentials = true;
}
// Create the Flow JSON for the current configuration
// opts.credentials (whether to include (known) credentials) - default: true
// opts.dimensions (whether to include node dimensions) - default: false
function createCompleteNodeSet(opts) {
var nns = [];
var i;
for (i=0;i<workspacesOrder.length;i++) {
@@ -989,22 +1035,22 @@ RED.nodes = (function() {
}
for (i in subflows) {
if (subflows.hasOwnProperty(i)) {
nns.push(convertSubflow(subflows[i], exportCredentials));
nns.push(convertSubflow(subflows[i], opts));
}
}
for (i in groups) {
if (groups.hasOwnProperty(i)) {
nns.push(convertNode(groups[i]));
nns.push(convertNode(groups[i], opts));
}
}
for (i in configNodes) {
if (configNodes.hasOwnProperty(i)) {
nns.push(convertNode(configNodes[i], exportCredentials));
nns.push(convertNode(configNodes[i], opts));
}
}
for (i in nodes) {
if (nodes.hasOwnProperty(i)) {
nns.push(convertNode(nodes[i], exportCredentials));
nns.push(convertNode(nodes[i], opts));
}
}
return nns;
@@ -2028,6 +2074,7 @@ RED.nodes = (function() {
if (configNode) {
if (configNode.users.indexOf(n) === -1) {
configNode.users.push(n);
RED.events.emit('nodes:change',configNode)
}
}
}

View File

@@ -36,7 +36,7 @@ var RED = (function() {
}
function loadPlugins(done) {
loader.reportProgress(RED._("event.loadPlugins",{count:""}), 17)
var lang = localStorage.getItem("editor-language")||i18n.detectLanguage();
var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
$.ajax({
headers: {
@@ -176,7 +176,7 @@ var RED = (function() {
function loadNodes() {
loader.reportProgress(RED._("event.loadNodes",{count:""}), 30)
var lang = localStorage.getItem("editor-language")||i18n.detectLanguage();
var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
$.ajax({
headers: {
@@ -540,6 +540,8 @@ var RED = (function() {
function showAbout() {
$.get('red/about', function(data) {
// data will be strictly markdown. Any HTML should be escaped.
data = RED.utils.sanitize(data);
var aboutHeader = '<div style="text-align:center;">'+
'<img width="50px" src="red/images/node-red-icon.svg" />'+
'</div>';
@@ -711,7 +713,7 @@ var RED = (function() {
throw new Error("RED already initialised");
}
initialised = true;
ace.require("ace/ext/language_tools");
if(window.ace) { window.ace.require("ace/ext/language_tools"); }
options = options || {};
options.apiRootUrl = options.apiRootUrl || "";
if (options.apiRootUrl && !/\/$/.test(options.apiRootUrl)) {

View File

@@ -143,7 +143,8 @@ RED.settings = (function () {
console.groupCollapsed("Versions");
console.log("jQuery",$().jquery)
console.log("jQuery UI",$.ui.version);
console.log("ACE",ace.version);
if(window.ace) { console.log("ACE",ace.version); }
if(window.monaco) { console.log("MONACO",monaco.version || "unknown"); }
console.log("D3",d3.version);
console.groupEnd();
loadUserSettings(done);

View File

@@ -452,7 +452,7 @@ RED.clipboard = (function() {
var libraries = RED.settings.libraries || [];
libraries.forEach(function(lib) {
var tabId = "red-ui-clipboard-dialog-import-tab-library-"+lib.id
var tabId = "red-ui-clipboard-dialog-import-tab-"+lib.id
tabs.addTab({
id: tabId,
label: RED._(lib.label||lib.id)
@@ -701,6 +701,13 @@ RED.clipboard = (function() {
var activeWorkspace = RED.workspaces.active();
nodes = RED.nodes.groups(activeWorkspace);
nodes = nodes.concat(RED.nodes.filterNodes({z:activeWorkspace}));
RED.nodes.eachConfig(function(n) {
if (n.z === RED.workspaces.active() && n._def.hasUsers === false) {
// Grab any config nodes scoped to this flow that don't
// require any flow-nodes to use them
nodes.push(n);
}
});
var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace);
nodes.unshift(parentNode);
nodes = RED.nodes.createExportableNodeSet(nodes);
@@ -1186,22 +1193,6 @@ RED.clipboard = (function() {
}
}
function getNodeLabelText(n) {
var label = n.name || n.type+": "+n.id;
if (n._def.label) {
try {
label = (typeof n._def.label === "function" ? n._def.label.call(n) : n._def.label)||"";
} catch(err) {
console.log("Definition error: "+n.type+".label",err);
}
}
var newlineIndex = label.indexOf("\\n");
if (newlineIndex > -1) {
label = label.substring(0,newlineIndex)+"...";
}
return label;
}
function getFlowLabel(n) {
n = JSON.parse(JSON.stringify(n));
n._def = RED.nodes.getType(n.type) || {};
@@ -1227,16 +1218,8 @@ RED.clipboard = (function() {
if (n._def) {
n._ = n._def._;
}
var div = $('<div>',{class:"red-ui-info-outline-item"});
RED.utils.createNodeIcon(n).appendTo(div);
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
var labelText = getNodeLabelText(n);
var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
if (labelText) {
label.text(labelText)
} else {
label.html(n.type)
}
var div = $('<div>',{class:"red-ui-node-list-item"});
RED.utils.createNodeIcon(n,true).appendTo(div);
return div;
}
@@ -1284,22 +1267,27 @@ RED.clipboard = (function() {
hideDropTarget();
})
.on("drop",function(event) {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
var data = event.originalEvent.dataTransfer.getData("text/plain");
data = data.substring(data.indexOf('['),data.lastIndexOf(']')+1);
importNodes(data);
} else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
var files = event.originalEvent.dataTransfer.files;
if (files.length === 1) {
var file = files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
importNodes(e.target.result);
};
})(file);
reader.readAsText(file);
try {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
var data = event.originalEvent.dataTransfer.getData("text/plain");
data = data.substring(data.indexOf('['),data.lastIndexOf(']')+1);
importNodes(data);
} else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) {
var files = event.originalEvent.dataTransfer.files;
if (files.length === 1) {
var file = files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
importNodes(e.target.result);
};
})(file);
reader.readAsText(file);
}
}
} catch(err) {
// Ensure any errors throw above doesn't stop the drop target from
// being hidden.
}
hideDropTarget();
event.preventDefault();

View File

@@ -18,7 +18,7 @@
/**
* options:
* - addButton : boolean|string - text for add label, default 'add'
* - buttons : array - list of custom buttons (objects with fields 'label', 'icon', 'title', 'click')
* - buttons : array - list of custom buttons (objects with fields 'id', 'label', 'icon', 'title', 'click')
* - height : number|'auto'
* - resize : function - called when list as a whole is resized
* - resizeItem : function(item) - called to resize individual item
@@ -94,7 +94,7 @@
}
buttons.forEach(function(button) {
var element = $('<a href="#" class="red-ui-button red-ui-button-small red-ui-editableList-addButton" style="margin-top: 4px; margin-right: 5px;"></a>')
var element = $('<button type="button" class="red-ui-button red-ui-button-small red-ui-editableList-addButton" style="margin-top: 4px; margin-right: 5px;"></button>')
.appendTo(that.topContainer)
.on("click", function(evt) {
evt.preventDefault();
@@ -103,6 +103,9 @@
}
});
if (button.id) {
element.attr("id", button.id);
}
if (button.title) {
element.attr("title", button.title);
}

View File

@@ -308,11 +308,9 @@ RED.popover = (function() {
// DOWN
if (currentItem.length > 0) {
if (currentItem.index() === menuOptions.length-1) {
console.log("WARP TO TOP")
// Wrap to top of list
list.children().first().children().first().focus();
} else {
console.log("GO DOWN ONE")
currentItem.next().children().first().focus();
}
} else {
@@ -323,11 +321,9 @@ RED.popover = (function() {
// UP
if (currentItem.length > 0) {
if (currentItem.index() === 0) {
console.log("WARP TO BOTTOM")
// Wrap to bottom of list
list.children().last().children().first().focus();
} else {
console.log("GO UP ONE")
currentItem.prev().children().first().focus();
}
} else {
@@ -363,7 +359,6 @@ RED.popover = (function() {
panel.css({ display: "none" });
panel.appendTo(document.body);
content.appendTo(panel);
var closeCallback;
function hide(dispose) {
$(document).off("mousedown.red-ui-popover-panel-close");
@@ -378,6 +373,7 @@ RED.popover = (function() {
}
function show(options) {
var closeCallback = options.onclose;
var closeButton = options.closeButton;
var target = options.target;
var align = options.align || "right";
var offset = options.offset || [0,0];
@@ -393,7 +389,7 @@ RED.popover = (function() {
top -= (top+panelHeight)-$(window).height() + 5;
}
if (top < 0) {
panelHeight.height(panelHeight+top)
panel.height(panelHeight+top)
top = 0;
}
if (align === "right") {
@@ -420,7 +416,8 @@ RED.popover = (function() {
});
$(document).on("mousedown.red-ui-popover-panel-close", function(event) {
if(!$(event.target).closest(panel).length && !$(event.target).closest(".red-ui-editor-dialog").length) {
var hitCloseButton = closeButton && $(event.target).closest(closeButton).length;
if(!hitCloseButton && !$(event.target).closest(panel).length && !$(event.target).closest(".red-ui-editor-dialog").length) {
if (closeCallback) {
closeCallback();
}

View File

@@ -100,7 +100,22 @@ RED.tabs = (function() {
if (options.scrollable) {
wrapper.addClass("red-ui-tabs-scrollable");
scrollContainer.addClass("red-ui-tabs-scroll-container");
scrollContainer.on("scroll",updateScroll);
scrollContainer.on("scroll",function(evt) {
// Generated by trackpads - not mousewheel
updateScroll(evt);
});
scrollContainer.on("wheel", function(evt) {
if (evt.originalEvent.deltaX === 0) {
// Prevent the scroll event from firing
evt.preventDefault();
// Assume this is wheel event which might not trigger
// the scroll event, so do things manually
var sl = scrollContainer.scrollLeft();
sl -= evt.originalEvent.deltaY;
scrollContainer.scrollLeft(sl);
}
})
scrollLeft = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-left"><a href="#" style="display:none;"><i class="fa fa-caret-left"></i></a></div>').appendTo(wrapper).find("a");
scrollLeft.on('mousedown',function(evt) { scrollEventHandler(evt,'-=150') }).on('click',function(evt){ evt.preventDefault();});
scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a");
@@ -373,7 +388,7 @@ RED.tabs = (function() {
var visibleCount = collapsedButtonsRow.children(":visible").length;
tabWidth = width - collapsedButtonsRow.width()-10;
var maxTabWidth = 198;
var minTabWidth = 80;
var minTabWidth = 120;
if (tabWidth <= minTabWidth || (tabWidth < maxTabWidth && visibleCount > 5)) {
// The tab is too small. Hide the next button to make room
// Start at the end of the button row, -1 for the menu button
@@ -770,6 +785,9 @@ RED.tabs = (function() {
count: function() {
return ul.find("li.red-ui-tab").length;
},
activeIndex: function() {
return ul.find("li.active").index()
},
contains: function(id) {
return ul.find("a[href='#"+id+"']").length > 0;
},

View File

@@ -48,7 +48,7 @@
});
this.button = $('<button type="button" class="red-ui-toggleButton '+baseClass+' toggle single"></button>');
if (enabledLabel || disabledLabel) {
this.buttonLabel = $("<span>").appendTo(this.button);
this.buttonLabel = $("<span>").appendTo(this.button).css("margin-left", "5px");
}
if (this.options.class) {

View File

@@ -312,7 +312,8 @@
}
if (child.depth !== parent.depth+1) {
child.depth = parent.depth+1;
var labelPaddingWidth = ((child.gutter ? child.gutter[0].offsetWidth + 2 : 0) + (child.depth * 20));
// var labelPaddingWidth = ((child.gutter ? child.gutter[0].offsetWidth + 2 : 0) + (child.depth * 20));
var labelPaddingWidth = ((child.gutter?child.gutter.width()+2:0)+(child.depth*20));
child.treeList.labelPadding.width(labelPaddingWidth+'px');
if (child.element) {
$(child.element).css({
@@ -350,10 +351,12 @@
delete that._items[item.id];
if(item.depth === 0) {
for(var key in that._items) {
var child = that._items[key];
if(child.parent && child.parent.id === item.id) {
delete that._items[key].treeList;
delete that._items[key];
if (that._items.hasOwnProperty(key)) {
var child = that._items[key];
if(child.parent && child.parent.id === item.id) {
delete that._items[key].treeList;
delete that._items[key];
}
}
}
that._data = that._data.filter(function(data) { return data.id !== item.id})
@@ -529,7 +532,8 @@
}).appendTo(label)
}
var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (depth * 20)
var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20);
// var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (depth * 20)
item.treeList.labelPadding = $('<span>').css({
display: "inline-block",
width: labelPaddingWidth+'px'

View File

@@ -1525,6 +1525,7 @@ var buildingEditDialog = false;
console.log("oneditresize",editing_node.id,editing_node.type,err.toString());
}
}
if (nodeInfoEditor) {nodeInfoEditor.resize();} //markdown editor doesnt size up without this - idkw!?
},
open: function(tray, done) {
if (editing_node.hasOwnProperty('outputs')) {
@@ -2759,98 +2760,11 @@ var buildingEditDialog = false;
}
}
function createEditor(options) {
var el = options.element || $("#"+options.id)[0];
var toolbarRow = $("<div>").appendTo(el);
el = $("<div>").appendTo(el).addClass("red-ui-editor-text-container")[0];
var editor = ace.edit(el);
editor.setTheme("ace/theme/tomorrow");
var session = editor.getSession();
session.on("changeAnnotation", function () {
var annotations = session.getAnnotations() || [];
var i = annotations.length;
var len = annotations.length;
while (i--) {
if (/doctype first\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
}
if (len > annotations.length) { session.setAnnotations(annotations); }
});
if (options.mode) {
session.setMode(options.mode);
}
if (options.foldStyle) {
session.setFoldStyle(options.foldStyle);
} else {
session.setFoldStyle('markbeginend');
}
if (options.options) {
editor.setOptions(options.options);
} else {
editor.setOptions({
enableBasicAutocompletion:true,
enableSnippets:true,
tooltipFollowsMouse: false
});
}
if (options.readOnly) {
editor.setOption('readOnly',options.readOnly);
editor.container.classList.add("ace_read-only");
}
if (options.hasOwnProperty('lineNumbers')) {
editor.renderer.setOption('showGutter',options.lineNumbers);
}
editor.$blockScrolling = Infinity;
if (options.value) {
session.setValue(options.value,-1);
}
if (options.globals) {
setTimeout(function() {
if (!!session.$worker) {
session.$worker.send("setOptions", [{globals: options.globals, maxerr:1000}]);
}
},100);
}
if (options.mode === 'ace/mode/markdown') {
$(el).addClass("red-ui-editor-text-container-toolbar");
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();
RED.editor.editMarkdown({
value: value,
width: "Infinity",
cursor: editor.getCursorPosition(),
complete: function(v,cursor) {
editor.setValue(v, -1);
editor.gotoLine(cursor.row+1,cursor.column,false);
setTimeout(function() {
editor.focus();
},300);
}
})
});
}
var helpButton = $('<button type="button" class="red-ui-editor-text-help red-ui-button red-ui-button-small"><i class="fa fa-question"></i></button>').appendTo($(el).parent());
RED.popover.create({
target: helpButton,
trigger: 'click',
size: "small",
direction: "left",
content: RED._("markdownEditor.format"),
autoClose: 50
});
session.setUseWrapMode(true);
}
return editor;
}
return {
init: function() {
ace.config.set('basePath', 'vendor/ace');
if(window.ace) { window.ace.config.set('basePath', 'vendor/ace'); }
RED.tray.init();
RED.actions.add("core:confirm-edit-tray", function() {
$(document.activeElement).blur();
@@ -2862,6 +2776,7 @@ var buildingEditDialog = false;
$("#node-dialog-cancel").trigger("click");
$("#node-config-dialog-cancel").trigger("click");
});
RED.editor.codeEditor.init();
},
edit: showEditDialog,
editConfig: showEditConfigNodeDialog,
@@ -2908,9 +2823,14 @@ var buildingEditDialog = false;
/**
* Create a editor ui component
* @param {object} options - the editor options
* @function
* @returs The code editor
* @memberof RED.editor
*/
createEditor: createEditor
createEditor: function(options) {
return RED.editor.codeEditor.create(options);
},
get customEditTypes() {
return customEditTypes;
}
}
})();

View File

@@ -0,0 +1,107 @@
/**
* 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.
**/
/**
* @namespace RED.editor.codeEditor
*/
RED.editor.codeEditor = (function() {
const MONACO = "monaco";
const ACE = "ace";
const defaultEditor = ACE;
const DEFAULT_SETTINGS = { lib: defaultEditor, options: {} };
var selectedCodeEditor = null;
var initialised = false;
function init() {
var codeEditorSettings = RED.editor.codeEditor.settings;
var editorChoice = codeEditorSettings.lib === MONACO ? MONACO : ACE;
try {
var browser = RED.utils.getBrowserInfo();
selectedCodeEditor = RED.editor.codeEditor[editorChoice];
//fall back to default code editor if there are any issues
if (!selectedCodeEditor || (editorChoice === MONACO && (browser.ie || !window.monaco))) {
selectedCodeEditor = RED.editor.codeEditor[defaultEditor];
}
initialised = selectedCodeEditor.init();
} catch (error) {
selectedCodeEditor = null;
console.warn("Problem initialising '" + editorChoice + "' code editor", error);
}
if(!initialised) {
selectedCodeEditor = RED.editor.codeEditor[defaultEditor];
initialised = selectedCodeEditor.init();
}
}
function create(options) {
//TODO: (quandry - for consideration)
// Below, I had to create a hidden element if options.id || options.element is not in the DOM
// I have seen 1 node calling `this.editor = RED.editor.createEditor()` with an
// invalid (non existing html element selector) (e.g. node-red-contrib-components does this)
// This causes monaco to throw an error when attempting to hook up its events to the dom & the rest of the 'oneditperapre'
// code is thus skipped.
// In ACE mode, creating an ACE editor (with an invalid ID) allows the editor to be created (but obviously there is no UI)
// Because one (or more) contrib nodes have left this bad code in place, how would we handle this?
// For compatibility, I have decided to create a hidden element so that at least an editor is created & errors do not occur.
// IMO, we should warn and exit as it is a coding error by the contrib author.
if (!options) {
console.warn("createEditor() options are missing");
options = {};
}
if (this.editor.type === MONACO) {
// compatibility (see above note)
if (!options.element && !options.id) {
options.id = 'node-backwards-compatability-dummy-editor';
}
options.element = options.element || $("#" + options.id)[0];
if (!options.element) {
console.warn("createEditor() options.element or options.id is not valid", options);
$("#dialog-form").append('<div id="' + options.id + '" style="display: none;" />');
}
return this.editor.create(options);
} else {
return this.editor.create(options);//fallback to ACE
}
}
return {
init: init,
/**
* Get editor settings object
* @memberof RED.editor.codeEditor
*/
get settings() {
return RED.settings.get('codeEditor') || DEFAULT_SETTINGS;
},
/**
* Get user selected code editor
* @return {string} Returns
* @memberof RED.editor.codeEditor
*/
get editor() {
return selectedCodeEditor;
},
/**
* Create a editor ui component
* @param {object} options - the editor options
* @memberof RED.editor.codeEditor
*/
create: create
}
})();

View File

@@ -0,0 +1,153 @@
/*
* 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.
**/
/**
* @namespace RED.editor.codeEditor.ace
*/
RED.editor.codeEditor.ace = (function() {
const type = "ace";
var initialised = false;
var initOptions = {};
function init(options) {
initOptions = options || {};
initialised = true;
return initialised;
}
function create(options) {
var editorSettings = RED.editor.codeEditor.settings || {};
var el = options.element || $("#"+options.id)[0];
var toolbarRow = $("<div>").appendTo(el);
el = $("<div>").appendTo(el).addClass("red-ui-editor-text-container")[0];
var editor = window.ace.edit(el);
editor.setTheme(editorSettings.theme || initOptions.theme || "ace/theme/tomorrow");
var session = editor.getSession();
session.on("changeAnnotation", function () {
var annotations = session.getAnnotations() || [];
var i = annotations.length;
var len = annotations.length;
while (i--) {
if (/doctype first\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
}
if (len > annotations.length) { session.setAnnotations(annotations); }
});
if (options.mode) {
session.setMode(options.mode);
}
if (options.foldStyle) {
session.setFoldStyle(options.foldStyle);
} else {
session.setFoldStyle('markbeginend');
}
if (options.options) {
editor.setOptions(options.options);
} else {
editor.setOptions({
enableBasicAutocompletion:true,
enableSnippets:true,
tooltipFollowsMouse: false
});
}
if (options.readOnly) {
editor.setOption('readOnly',options.readOnly);
editor.container.classList.add("ace_read-only");
}
if (options.hasOwnProperty('lineNumbers')) {
editor.renderer.setOption('showGutter',options.lineNumbers);
}
editor.$blockScrolling = Infinity;
if (options.value) {
session.setValue(options.value,-1);
}
if (options.globals) {
setTimeout(function() {
if (!!session.$worker) {
session.$worker.send("setOptions", [{globals: options.globals, maxerr:1000}]);
}
},100);
}
if (options.mode === 'ace/mode/markdown') {
$(el).addClass("red-ui-editor-text-container-toolbar");
editor.toolbar = RED.editor.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();
RED.editor.editMarkdown({
value: value,
width: "Infinity",
cursor: editor.getCursorPosition(),
complete: function(v,cursor) {
editor.setValue(v, -1);
editor.gotoLine(cursor.row+1,cursor.column,false);
setTimeout(function() {
editor.focus();
},300);
}
})
});
}
var helpButton = $('<button type="button" class="red-ui-editor-text-help red-ui-button red-ui-button-small"><i class="fa fa-question"></i></button>').appendTo($(el).parent());
RED.popover.create({
target: helpButton,
trigger: 'click',
size: "small",
direction: "left",
content: RED._("markdownEditor.format"),
autoClose: 50
});
session.setUseWrapMode(true);
}
editor._destroy = editor.destroy;
editor.destroy = function() {
try {
this._destroy();
} catch (e) { }
$(el).remove();
$(toolbarRow).remove();
}
editor.type = type;
return editor;
}
return {
/**
* Editor type
* @memberof RED.editor.codeEditor.ace
*/
get type() { return type; },
/**
* Editor initialised
* @memberof RED.editor.codeEditor.ace
*/
get initialised() { return initialised; },
/**
* Initialise code editor
* @param {object} options - initialisation options
* @memberof RED.editor.codeEditor.ace
*/
init: init,
/**
* Create a code editor
* @param {object} options - the editor options
* @memberof RED.editor.codeEditor.ace
*/
create: create
}
})();

File diff suppressed because it is too large Load Diff

View File

@@ -121,73 +121,75 @@
var currentFunctionMarker = null;
expressionEditor.getSession().setValue(value||"",-1);
expressionEditor.on("changeSelection", function() {
var c = expressionEditor.getCursorPosition();
var token = expressionEditor.getSession().getTokenAt(c.row,c.column);
if (token !== currentToken || (token && /paren/.test(token.type) && c.column !== currentTokenPos)) {
currentToken = token;
var r,p;
var scopedFunction = null;
if (token && token.type === 'keyword') {
r = c.row;
scopedFunction = token;
} else {
var depth = 0;
var next = false;
if (token) {
if (token.type === 'paren.rparen') {
// If this is a block of parens ')))', set
// depth to offset against the cursor position
// within the block
currentTokenPos = c.column;
depth = c.column - (token.start + token.value.length);
}
//ace only (monaco has jsonata tokeniser)
if(expressionEditor.type == "ace") {
expressionEditor.on("changeSelection", function() {
var c = expressionEditor.getCursorPosition();
var token = expressionEditor.getSession().getTokenAt(c.row,c.column);
if (token !== currentToken || (token && /paren/.test(token.type) && c.column !== currentTokenPos)) {
currentToken = token;
var r,p;
var scopedFunction = null;
if (token && token.type === 'keyword') {
r = c.row;
p = token.index;
scopedFunction = token;
} else {
r = c.row-1;
p = -1;
}
while ( scopedFunction === null && r > -1) {
var rowTokens = expressionEditor.getSession().getTokens(r);
if (p === -1) {
p = rowTokens.length-1;
var depth = 0;
var next = false;
if (token) {
if (token.type === 'paren.rparen') {
// If this is a block of parens ')))', set
// depth to offset against the cursor position
// within the block
currentTokenPos = c.column;
depth = c.column - (token.start + token.value.length);
}
r = c.row;
p = token.index;
} else {
r = c.row-1;
p = -1;
}
while (p > -1) {
var type = rowTokens[p].type;
if (next) {
if (type === 'keyword') {
scopedFunction = rowTokens[p];
// console.log("HIT",scopedFunction);
break;
while ( scopedFunction === null && r > -1) {
var rowTokens = expressionEditor.getSession().getTokens(r);
if (p === -1) {
p = rowTokens.length-1;
}
while (p > -1) {
var type = rowTokens[p].type;
if (next) {
if (type === 'keyword') {
scopedFunction = rowTokens[p];
// console.log("HIT",scopedFunction);
break;
}
next = false;
}
next = false;
if (type === 'paren.lparen') {
depth-=rowTokens[p].value.length;
} else if (type === 'paren.rparen') {
depth+=rowTokens[p].value.length;
}
if (depth < 0) {
next = true;
depth = 0;
}
// console.log(r,p,depth,next,rowTokens[p]);
p--;
}
if (type === 'paren.lparen') {
depth-=rowTokens[p].value.length;
} else if (type === 'paren.rparen') {
depth+=rowTokens[p].value.length;
if (!scopedFunction) {
r--;
}
if (depth < 0) {
next = true;
depth = 0;
}
// console.log(r,p,depth,next,rowTokens[p]);
p--;
}
if (!scopedFunction) {
r--;
}
}
expressionEditor.session.removeMarker(currentFunctionMarker);
if (scopedFunction) {
//console.log(token,.map(function(t) { return t.type}));
funcSelect.val(scopedFunction.value).trigger("change");
}
}
expressionEditor.session.removeMarker(currentFunctionMarker);
if (scopedFunction) {
//console.log(token,.map(function(t) { return t.type}));
funcSelect.val(scopedFunction.value).trigger("change");
}
}
});
});
}
dialogForm.i18n();
$("#red-ui-editor-type-expression-func-insert").on("click", function(e) {
e.preventDefault();
@@ -343,6 +345,7 @@
}
expressionEditor.destroy();
testDataEditor.destroy();
testResultEditor.destroy();
},
show: function() {}
}

View File

@@ -602,10 +602,10 @@
},
close: function() {
// expressionEditor.destroy();
if (options.onclose) {
options.onclose();
}
expressionEditor.destroy();
},
show: function() {}
}

View File

@@ -73,6 +73,7 @@ RED.eventLog = (function() {
var trayBody = tray.find('.red-ui-tray-body');
var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor');
eventLogEditor = RED.editor.createEditor({
mode:"ace/mode/shell",
id: 'red-ui-event-log-editor',
value: backlog.join("\n"),
lineNumbers: false,

View File

@@ -27,7 +27,7 @@ RED.library = (function() {
'<div class="red-ui-panel" id="red-ui-library-dialog-load-browser"></div>'+
'<div class="red-ui-panel">'+
'<div id="red-ui-library-dialog-load-preview">'+
'<div class="red-ui-panel" id="red-ui-library-dialog-load-preview-text"></div>'+
'<div class="red-ui-panel" id="red-ui-library-dialog-load-preview-text" style="position:relative; height: 50%; overflow-y: hidden;"></div>'+
'<div class="red-ui-panel" id="red-ui-library-dialog-load-preview-details">'+
'<table id="red-ui-library-dialog-load-preview-details-table" class="red-ui-info-table"></table>'+
'</div>'+
@@ -216,21 +216,27 @@ RED.library = (function() {
{ id:'node-input-'+options.type+'-menu-open-library',
label: RED._("library.openLibrary"),
onselect: function() {
libraryEditor = ace.edit('red-ui-library-dialog-load-preview-text',{
useWorker: false
});
libraryEditor.setTheme("ace/theme/tomorrow");
if (options.mode) {
libraryEditor.getSession().setMode(options.mode);
}
libraryEditor.setOptions({
var editorOpts = {
id: 'red-ui-library-dialog-load-preview-text',
mode: options.mode,
readOnly: true,
highlightActiveLine: false,
highlightGutterLine: false
});
libraryEditor.renderer.$cursorLayer.element.style.opacity=0;
libraryEditor.$blockScrolling = Infinity;
highlightGutterLine: false,
contextmenu: false
}
libraryEditor = RED.editor.createEditor(editorOpts); //use red.editor
if(libraryEditor.isACE) {
if (options.mode) {
libraryEditor.getSession().setMode(options.mode);
}
libraryEditor.setOptions({
readOnly: true,
highlightActiveLine: false,
highlightGutterLine: false
});
libraryEditor.renderer.$cursorLayer.element.style.opacity=0;
libraryEditor.$blockScrolling = Infinity;
}
activeLibrary = options;
var listing = [];
@@ -809,11 +815,12 @@ RED.library = (function() {
open: function(e) {
RED.keyboard.disable();
$(this).parent().find(".ui-dialog-titlebar-close").hide();
libraryEditor.resize();
},
close: function(e) {
RED.keyboard.enable();
if (libraryEditor) {
libraryEditor.destroy();
libraryEditor.remove();
libraryEditor = null;
}
}

View File

@@ -320,12 +320,12 @@ RED.palette = (function() {
var paletteNode = getPaletteNode(nt);
ui.originalPosition.left = paletteNode.offset().left;
mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop();
mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop() + 10;
if (!groupTimer) {
groupTimer = setTimeout(function() {
mouseX /= RED.view.scale();
mouseY /= RED.view.scale();
var group = RED.view.getGroupAtPoint(mouseX,mouseY);
var mx = mouseX / RED.view.scale();
var my = mouseY / RED.view.scale();
var group = RED.view.getGroupAtPoint(mx,my);
if (group !== hoverGroup) {
if (hoverGroup) {
document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
@@ -357,23 +357,20 @@ RED.palette = (function() {
svgRect.width = 1;
svgRect.height = 1;
nodes = chartSVG.getIntersectionList(svgRect,chartSVG);
mouseX /= RED.view.scale();
mouseY /= RED.view.scale();
} else {
// Firefox doesn't do getIntersectionList and that
// makes us sad
mouseX /= RED.view.scale();
mouseY /= RED.view.scale();
nodes = RED.view.getLinksAtPoint(mouseX,mouseY);
}
var mx = mouseX / RED.view.scale();
var my = mouseY / RED.view.scale();
for (var i=0;i<nodes.length;i++) {
var node = d3.select(nodes[i]);
if (node.classed('red-ui-flow-link-background') && !node.classed('red-ui-flow-link-link')) {
var length = nodes[i].getTotalLength();
for (var j=0;j<length;j+=10) {
var p = nodes[i].getPointAtLength(j);
var d2 = ((p.x-mouseX)*(p.x-mouseX))+((p.y-mouseY)*(p.y-mouseY));
var d2 = ((p.x-mx)*(p.x-mx))+((p.y-my)*(p.y-my));
if (d2 < 200 && d2 < bestDistance) {
bestDistance = d2;
bestLink = nodes[i];

View File

@@ -199,7 +199,7 @@ RED.sidebar = (function() {
id = RED.settings.get("editor.sidebar.order",["info", "help", "version-control", "debug"])[0]
}
if (id) {
if (!containsTab(id)) {
if (!containsTab(id) && knownTabs[id]) {
sidebar_tabs.addTab(knownTabs[id]);
}
sidebar_tabs.activateTab(id);

View File

@@ -230,10 +230,17 @@ RED.sidebar.help = (function() {
}
function getNodeLabel(n) {
var div = $('<div>',{class:"red-ui-info-outline-item"});
RED.utils.createNodeIcon(n).appendTo(div);
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
$('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).text(n.name||n.type).appendTo(contentDiv);
var div = $('<div>',{class:"red-ui-node-list-item"});
var icon = RED.utils.createNodeIcon(n).appendTo(div);
var label = n.name;
if (!label && n._def.paletteLabel) {
try {
label = (typeof n._def.paletteLabel === "function" ? n._def.paletteLabel.call(n._def) : n._def.paletteLabel)||"";
} catch (err) {
}
}
label = label || n.type;
$('<div>',{class:"red-ui-node-label"}).text(n.name||n.type).appendTo(icon);
return div;
}
@@ -248,7 +255,15 @@ RED.sidebar.help = (function() {
title = subflowNode.name || nodeType;
} else {
helpText = RED.nodes.getNodeHelp(nodeType)||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
title = nodeType;
var _def = RED.nodes.registry.getNodeType(nodeType);
title = (_def && _def.paletteLabel)?_def.paletteLabel:nodeType;
if (typeof title === "function") {
try {
title = _def.paletteLabel.call(_def);
} catch(err) {
title = nodeType;
}
}
}
setInfoText(title, helpText, helpSection);

View File

@@ -73,36 +73,11 @@ RED.sidebar.info.outliner = (function() {
return item;
}
function getNodeLabelText(n) {
var label = n.name || n.type+": "+n.id;
if (n._def.label) {
try {
label = (typeof n._def.label === "function" ? n._def.label.call(n) : n._def.label)||"";
} catch(err) {
console.log("Definition error: "+n.type+".label",err);
}
}
var newlineIndex = label.indexOf("\\n");
if (newlineIndex > -1) {
label = label.substring(0,newlineIndex)+"...";
}
return label;
}
function getNodeLabel(n) {
var div = $('<div>',{class:"red-ui-info-outline-item"});
RED.utils.createNodeIcon(n).appendTo(div);
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
var labelText = getNodeLabelText(n);
var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
if (labelText) {
label.text(labelText)
} else {
label.html("&nbsp;")
}
var div = $('<div>',{class:"red-ui-node-list-item red-ui-info-outline-item"});
RED.utils.createNodeIcon(n, true).appendTo(div);
div.find(".red-ui-node-label").addClass("red-ui-info-outline-item-label")
addControls(n, div);
return div;
}
@@ -430,7 +405,7 @@ RED.sidebar.info.outliner = (function() {
var existingObject = objects[n.id];
var parent = n.g||n.z||"__global__";
var nodeLabelText = getNodeLabelText(n);
var nodeLabelText = RED.utils.getNodeLabel(n,n.name || (n.type+": "+n.id));
if (nodeLabelText) {
existingObject.element.find(".red-ui-info-outline-item-label").text(nodeLabelText);
} else {

View File

@@ -477,7 +477,7 @@ RED.sidebar.info = (function() {
return;
}
}
while ((m=/(\[(.*?)\])/.exec(tip))) {
while ((m=/(\[([a-z]*?)\])/.exec(tip))) {
tip = tip.replace(m[1],RED.keyboard.formatKey(m[2]));
}
tipBox.html(tip).fadeIn(200);
@@ -499,7 +499,7 @@ RED.sidebar.info = (function() {
if (tipCount === -1) {
do {
tipCount++;
} while(RED._("infotips:info.tip"+tipCount)!=="infotips:info.tip"+tipCount);
} while(RED._("infotips:info.tip"+tipCount)!=="info.tip"+tipCount);
}
startTimeout = setTimeout(setTip,startDelay);
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.tray = (function() {
RED.tray = (function() {
var stack = [];
var editorStack;
@@ -166,6 +166,8 @@ RED.tray = (function() {
setTimeout(function() {
// Delay resetting the flag, so we don't close prematurely
openingTray = false;
raiseTrayZ();
handleWindowResize();//cause call to monaco layout
},200);
body.find(":focusable:first").trigger("focus");
@@ -206,6 +208,17 @@ RED.tray = (function() {
}
}
//raise tray z-index to prevent editor context menu being clipped by sidebar
function raiseTrayZ() {
setTimeout(function(){
$('#red-ui-editor-stack').css("zIndex","13");
},300);
}
//lower tray z-index back to original place for correct slide animation (related to fix for editor context menu clipped by sidebar)
function lowerTrayZ(){
$('#red-ui-editor-stack').css("zIndex","9");
}
return {
init: function init() {
editorStack = $("#red-ui-editor-stack");
@@ -221,6 +234,7 @@ RED.tray = (function() {
});
},
show: function show(options) {
lowerTrayZ();
if (!options) {
if (stack.length > 0) {
var tray = stack[stack.length-1];
@@ -246,12 +260,16 @@ RED.tray = (function() {
showTray(options);
},250)
} else {
if (stack.length > 0) {
stack[stack.length-1].tray.css("z-index", 0);
}
RED.events.emit("editor:open");
showTray(options);
}
},
hide: function hide() {
lowerTrayZ();
if (stack.length > 0) {
var tray = stack[stack.length-1];
tray.tray.css({
@@ -266,15 +284,16 @@ RED.tray = (function() {
},
resize: handleWindowResize,
close: function close(done) {
lowerTrayZ(); //lower tray z-index for correct animation
if (stack.length > 0) {
var tray = stack.pop();
tray.tray.css({
right: -(tray.tray.width()+10)+"px"
});
setTimeout(function() {
if (tray.options.close) {
tray.options.close();
}
try {
if (tray.options.close) { tray.options.close(); }
} catch (ex) { }
tray.tray.remove();
if (stack.length > 0) {
var oldTray = stack[stack.length-1];
@@ -284,6 +303,8 @@ RED.tray = (function() {
handleWindowResize();
oldTray.tray.css({right:0});
if (oldTray.options.show) {
raiseTrayZ();
handleWindowResize();//cause call to monaco layout
oldTray.options.show();
}
},0);
@@ -304,6 +325,8 @@ RED.tray = (function() {
$(".red-ui-sidebar-shade").hide();
RED.events.emit("editor:close");
RED.view.focus();
} else {
stack[stack.length-1].tray.css("z-index", "auto");
}
},250)
}

View File

@@ -58,6 +58,10 @@ RED.utils = (function() {
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('buffer['+value.length+']');
} else if (value.hasOwnProperty('type') && value.type === 'array' && value.hasOwnProperty('data')) {
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('array['+value.length+']');
} else if (value.hasOwnProperty('type') && value.type === 'set' && value.hasOwnProperty('data')) {
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('set['+value.length+']');
} else if (value.hasOwnProperty('type') && value.type === 'map' && value.hasOwnProperty('data')) {
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('map');
} else if (value.hasOwnProperty('type') && value.type === 'function') {
result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('function');
} else if (value.hasOwnProperty('type') && (value.type === 'number' || value.type === 'bigint')) {
@@ -178,8 +182,14 @@ RED.utils = (function() {
RED.popover.tooltip(pinPath,RED._("node-red:debug.sidebar.pinPath"));
}
if (extraTools) {
extraTools.addClass("red-ui-debug-msg-tools-other");
extraTools.appendTo(tools);
var t = extraTools;
if (typeof t === 'function') {
t = t(key,msg);
}
if (t) {
t.addClass("red-ui-debug-msg-tools-other");
t.appendTo(tools);
}
}
}
function checkExpanded(strippedKey,expandPaths,minRange,maxRange) {
@@ -344,7 +354,7 @@ RED.utils = (function() {
var isArray = Array.isArray(obj);
var isArrayObject = false;
if (obj && typeof obj === 'object' && obj.hasOwnProperty('type') && obj.hasOwnProperty('data') && ((obj.__enc__ && obj.type === 'array') || obj.type === 'Buffer')) {
if (obj && typeof obj === 'object' && obj.hasOwnProperty('type') && obj.hasOwnProperty('data') && ((obj.__enc__ && obj.type === 'set') || (obj.__enc__ && obj.type === 'array') || obj.type === 'Buffer')) {
isArray = true;
isArrayObject = true;
}
@@ -411,7 +421,7 @@ RED.utils = (function() {
}
var fullLength = data.length;
if (originalLength > 0) {
if (originalLength > 0) {
$('<i class="fa fa-caret-right red-ui-debug-msg-object-handle"></i> ').prependTo(header);
var arrayRows = $('<div class="red-ui-debug-msg-array-rows"></div>').appendTo(element);
element.addClass('red-ui-debug-msg-buffer-raw');
@@ -476,7 +486,8 @@ RED.utils = (function() {
rootPath: rootPath,
expandPaths: expandPaths,
ontoggle: ontoggle,
exposeApi: exposeApi
exposeApi: exposeApi,
tools: tools
}
).appendTo(row);
}
@@ -504,8 +515,8 @@ RED.utils = (function() {
rootPath: rootPath,
expandPaths: expandPaths,
ontoggle: ontoggle,
exposeApi: exposeApi
exposeApi: exposeApi,
tools: tools
}
).appendTo(row);
}
@@ -525,12 +536,18 @@ RED.utils = (function() {
}
} else if (typeof obj === 'object') {
element.addClass('collapsed');
var keys = Object.keys(obj);
var data = obj;
var type = "object";
if (data.__enc__) {
data = data.data;
type = obj.type.toLowerCase();
}
var keys = Object.keys(data);
if (key || keys.length > 0) {
$('<i class="fa fa-caret-right red-ui-debug-msg-object-handle"></i> ').prependTo(header);
makeExpandable(header, function() {
if (!key) {
$('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-type-header"></span>').text('object').appendTo(header);
$('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-type-header"></span>').text(type).appendTo(header);
}
for (i=0;i<keys.length;i++) {
var row = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(element);
@@ -543,7 +560,7 @@ RED.utils = (function() {
}
}
subElements[newPath] = buildMessageElement(
obj[keys[i]],
data[keys[i]],
{
key: keys[i],
typeHint: false,
@@ -553,8 +570,8 @@ RED.utils = (function() {
rootPath: rootPath,
expandPaths: expandPaths,
ontoggle: ontoggle,
exposeApi: exposeApi
exposeApi: exposeApi,
tools: tools
}
).appendTo(row);
}
@@ -566,7 +583,7 @@ RED.utils = (function() {
checkExpanded(strippedKey,expandPaths));
}
if (key) {
$('<span class="red-ui-debug-msg-type-meta"></span>').text('object').appendTo(entryObj);
$('<span class="red-ui-debug-msg-type-meta"></span>').text(type).appendTo(entryObj);
} else {
headerHead = $('<span class="red-ui-debug-msg-object-header"></span>').appendTo(entryObj);
$('<span>{ </span>').appendTo(headerHead);
@@ -574,7 +591,7 @@ RED.utils = (function() {
for (i=0;i<keysLength;i++) {
$('<span class="red-ui-debug-msg-object-key"></span>').text(keys[i]).appendTo(headerHead);
$('<span>: </span>').appendTo(headerHead);
buildMessageSummaryValue(obj[keys[i]]).appendTo(headerHead);
buildMessageSummaryValue(data[keys[i]]).appendTo(headerHead);
if (i < keysLength-1) {
$('<span>, </span>').appendTo(headerHead);
}
@@ -856,6 +873,7 @@ RED.utils = (function() {
obj[key] = value;
}
}
function separateIconPath(icon) {
var result = {module: "", file: ""};
if (icon) {
@@ -863,10 +881,10 @@ RED.utils = (function() {
if (index === 0) {
icon = icon.substring((RED.settings.apiRootUrl+'icons/').length);
}
index = icon.indexOf('/');
if (index !== -1) {
result.module = icon.slice(0, index);
result.file = icon.slice(index + 1);
var match = /^((?:@[^/]+\/)?[^/]+)\/(.*)$/.exec(icon);
if (match) {
result.module = match[1];
result.file = match[2];
} else {
result.file = icon;
}
@@ -875,6 +893,7 @@ RED.utils = (function() {
}
function getDefaultNodeIcon(def,node) {
def = def || {};
var icon_url;
if (node && node.type === "subflow") {
icon_url = "node-red/subflow.svg";
@@ -912,6 +931,7 @@ RED.utils = (function() {
}
function getNodeIcon(def,node) {
def = def || {};
if (node && node.type === '_selection_') {
return "font-awesome/fa-object-ungroup";
} else if (node && node.type === 'group') {
@@ -999,6 +1019,7 @@ RED.utils = (function() {
}
function getNodeColor(type, def) {
def = def || {};
var result = def.color;
var paletteTheme = RED.settings.theme('palette.theme') || [];
if (paletteTheme.length > 0) {
@@ -1051,7 +1072,7 @@ RED.utils = (function() {
payload = Infinity;
} else if ((format === 'number') && (payload === "-Infinity")) {
payload = -Infinity;
} else if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) {
} else if (format === 'Object' || /^(array|set|map)/.test(format) || format === 'boolean' || format === 'number' ) {
payload = JSON.parse(payload);
} else if (/error/i.test(format)) {
payload = JSON.parse(payload);
@@ -1125,9 +1146,11 @@ RED.utils = (function() {
imageIconElement.css("backgroundImage", "url("+iconUrl+")");
}
function createNodeIcon(node) {
function createNodeIcon(node, includeLabel) {
var container = $('<span class="red-ui-node-icon-container">');
var def = node._def;
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"})
var nodeDiv = $('<div>',{class:"red-ui-node-icon"})
if (node.type === "_selection_") {
nodeDiv.addClass("red-ui-palette-icon-selection");
} else if (node.type === "group") {
@@ -1147,9 +1170,20 @@ RED.utils = (function() {
}
var icon_url = RED.utils.getNodeIcon(def,node);
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
RED.utils.createIconElement(icon_url, iconContainer, true);
return nodeDiv;
RED.utils.createIconElement(icon_url, nodeDiv, true);
nodeDiv.appendTo(container);
if (includeLabel) {
var labelText = RED.utils.getNodeLabel(node,node.name || (node.type+": "+node.id));
var label = $('<div>',{class:"red-ui-node-label"}).appendTo(container);
if (labelText) {
label.text(labelText)
} else {
label.html("&nbsp;")
}
}
return container;
}
function getDarkerColor(c) {
@@ -1234,6 +1268,23 @@ RED.utils = (function() {
}
return false;
}
function getBrowserInfo() {
var r = {}
try {
var ua = navigator.userAgent;
r.ua = ua;
r.browser = /Edge\/\d+/.test(ua) ? 'ed' : /MSIE 9/.test(ua) ? 'ie9' : /MSIE 10/.test(ua) ? 'ie10' : /MSIE 11/.test(ua) ? 'ie11' : /MSIE\s\d/.test(ua) ? 'ie?' : /rv\:11/.test(ua) ? 'ie11' : /Firefox\W\d/.test(ua) ? 'ff' : /Chrom(e|ium)\W\d|CriOS\W\d/.test(ua) ? 'gc' : /\bSafari\W\d/.test(ua) ? 'sa' : /\bOpera\W\d/.test(ua) ? 'op' : /\bOPR\W\d/i.test(ua) ? 'op' : typeof MSPointerEvent !== 'undefined' ? 'ie?' : '';
r.os = /Windows NT 10/.test(ua) ? "win10" : /Windows NT 6\.0/.test(ua) ? "winvista" : /Windows NT 6\.1/.test(ua) ? "win7" : /Windows NT 6\.\d/.test(ua) ? "win8" : /Windows NT 5\.1/.test(ua) ? "winxp" : /Windows NT [1-5]\./.test(ua) ? "winnt" : /Mac/.test(ua) ? "mac" : /Linux/.test(ua) ? "linux" : /X11/.test(ua) ? "nix" : "";
r.touch = 'ontouchstart' in document.documentElement;
r.mobile = /IEMobile|Windows Phone|Lumia/i.test(ua) ? 'w' : /iPhone|iP[oa]d/.test(ua) ? 'i' : /Android/.test(ua) ? 'a' : /BlackBerry|PlayBook|BB10/.test(ua) ? 'b' : /Mobile Safari/.test(ua) ? 's' : /webOS|Mobile|Tablet|Opera Mini|\bCrMo\/|Opera Mobi/i.test(ua) ? 1 : 0;
r.tablet = /Tablet|iPad/i.test(ua);
r.ie = /MSIE \d|Trident.*rv:/.test(navigator.userAgent);
r.android = /android/i.test(navigator.userAgent);
} catch (error) { }
return r;
}
return {
createObjectElement: buildMessageElement,
getMessageProperty: getMessageProperty,
@@ -1255,6 +1306,7 @@ RED.utils = (function() {
createNodeIcon: createNodeIcon,
getDarkerColor: getDarkerColor,
parseModuleList: parseModuleList,
checkModuleAllowed: checkModuleAllowed
checkModuleAllowed: checkModuleAllowed,
getBrowserInfo: getBrowserInfo
}
})();

View File

@@ -0,0 +1,151 @@
RED.view.annotations = (function() {
var annotations = {};
function init() {
RED.hooks.add("viewRedrawNode.annotations", function(evt) {
try {
if (evt.node.__pendingAnnotation__) {
addAnnotation(evt.node.__pendingAnnotation__,evt);
delete evt.node.__pendingAnnotation__;
}
var badgeDX = 0;
var controlDX = 0;
for (var i=0,l=evt.el.__annotations__.length;i<l;i++) {
var annotation = evt.el.__annotations__[i];
if (annotations.hasOwnProperty(annotation.id)) {
var opts = annotations[annotation.id];
var showAnnotation = true;
var isBadge = opts.type === 'badge';
if (opts.show !== undefined) {
if (typeof opts.show === "string") {
showAnnotation = !!evt.node[opts.show]
} else if (typeof opts.show === "function"){
showAnnotation = opts.show(evt.node)
} else {
showAnnotation = !!opts.show;
}
annotation.element.classList.toggle("hide", !showAnnotation);
}
if (isBadge) {
if (showAnnotation) {
var rect = annotation.element.getBoundingClientRect();
badgeDX += rect.width;
annotation.element.setAttribute("transform", "translate("+(evt.node.w-3-badgeDX)+", -8)");
badgeDX += 4;
}
} else {
if (showAnnotation) {
var rect = annotation.element.getBoundingClientRect();
annotation.element.setAttribute("transform", "translate("+(3+controlDX)+", -12)");
controlDX += rect.width + 4;
}
}
} else {
annotation.element.parentNode.removeChild(annotation.element);
evt.el.__annotations__.splice(i,1);
i--;
l--;
}
}
}catch(err) {
console.log(err)
}
});
}
/**
* Register a new node annotation
* @param {string} id - unique identifier
* @param {type} opts - annotations options
*
* opts: {
* type: "badge"
* class: "",
* element: function(node),
* show: string|function(node),
* filter: function(node) -> boolean
* }
*/
function register(id, opts) {
if (opts.type !== 'badge') {
throw new Error("Unsupported annotation type: "+opts.type);
}
annotations[id] = opts
RED.hooks.add("viewAddNode.annotation-"+id, function(evt) {
if (opts.filter && !opts.filter(evt.node)) {
return;
}
addAnnotation(id,evt);
});
var nodes = RED.view.getActiveNodes();
nodes.forEach(function(n) {
n.__pendingAnnotation__ = id;
})
RED.view.redraw();
}
function addAnnotation(id,evt) {
var opts = annotations[id];
evt.el.__annotations__ = evt.el.__annotations__ || [];
var annotationGroup = document.createElementNS("http://www.w3.org/2000/svg","g");
annotationGroup.setAttribute("class",opts.class || "");
evt.el.__annotations__.push({
id:id,
element: annotationGroup
});
var annotation = opts.element(evt.node);
if (opts.tooltip) {
annotation.addEventListener("mouseenter", getAnnotationMouseEnter(annotation,evt.node,opts.tooltip));
annotation.addEventListener("mouseleave", annotationMouseLeave);
}
annotationGroup.appendChild(annotation);
evt.el.appendChild(annotationGroup);
}
function unregister(id) {
delete annotations[id]
RED.hooks.remove("*.annotation-"+id);
RED.view.redraw();
}
var badgeHoverTimeout;
var badgeHover;
function getAnnotationMouseEnter(annotation,node,tooltip) {
return function() {
var text = typeof tooltip === "function"?tooltip(node):tooltip;
if (text) {
clearTimeout(badgeHoverTimeout);
badgeHoverTimeout = setTimeout(function() {
var pos = RED.view.getElementPosition(annotation);
var rect = annotation.getBoundingClientRect();
badgeHoverTimeout = null;
badgeHover = RED.view.showTooltip(
(pos[0]+rect.width/2),
(pos[1]),
text,
"top"
);
},500);
}
}
}
function annotationMouseLeave() {
clearTimeout(badgeHoverTimeout);
if (badgeHover) {
badgeHover.remove();
badgeHover = null;
}
}
return {
init: init,
register:register,
unregister:unregister
}
})();

View File

@@ -546,10 +546,44 @@ RED.view = (function() {
}
});
RED.view.annotations.init();
RED.view.navigator.init();
RED.view.tools.init();
RED.view.annotations.register("red-ui-flow-node-changed",{
type: "badge",
class: "red-ui-flow-node-changed",
element: function() {
var changeBadge = document.createElementNS("http://www.w3.org/2000/svg","circle");
changeBadge.setAttribute("cx",5);
changeBadge.setAttribute("cy",5);
changeBadge.setAttribute("r",5);
return changeBadge;
},
show: function(n) { return n.changed||n.moved }
})
RED.view.annotations.register("red-ui-flow-node-error",{
type: "badge",
class: "red-ui-flow-node-error",
element: function(d) {
var errorBadge = document.createElementNS("http://www.w3.org/2000/svg","path");
errorBadge.setAttribute("d","M 0,9 l 10,0 -5,-8 z");
return errorBadge
},
tooltip: function(d) {
if (d.validationErrors && d.validationErrors.length > 0) {
return RED._("editor.errors.invalidProperties")+"\n - "+d.validationErrors.join("\n - ")
}
},
show: function(n) { return !n.valid }
})
}
function updateGrid() {
var gridTicks = [];
for (var i=0;i<space_width;i+=+gridSize) {
@@ -1476,15 +1510,15 @@ RED.view = (function() {
var mouseY = node.n.y;
if (outer[0][0].getIntersectionList) {
var svgRect = outer[0][0].createSVGRect();
svgRect.x = mouseX;
svgRect.y = mouseY;
svgRect.x = mouseX*scaleFactor;
svgRect.y = mouseY*scaleFactor;
svgRect.width = 1;
svgRect.height = 1;
nodes = outer[0][0].getIntersectionList(svgRect, outer[0][0]);
} else {
// Firefox doesn"t do getIntersectionList and that
// makes us sad
nodes = RED.view.getLinksAtPoint(mouseX,mouseY);
nodes = RED.view.getLinksAtPoint(mouseX*scaleFactor,mouseY*scaleFactor);
}
for (var i=0;i<nodes.length;i++) {
if (d3.select(nodes[i]).classed("red-ui-flow-link-background")) {
@@ -3445,6 +3479,7 @@ RED.view = (function() {
}
}
function getGroupAt(x,y) {
// x,y expected to be in node-co-ordinate space
var candidateGroups = {};
for (var i=0;i<activeGroups.length;i++) {
var g = activeGroups[i];
@@ -3596,31 +3631,6 @@ RED.view = (function() {
}
}
function errorBadgeMouseEnter(e) {
var d = this.__data__;
if (d.validationErrors && d.validationErrors.length > 0) {
clearTimeout(portLabelHoverTimeout);
var node = this;
portLabelHoverTimeout = setTimeout(function() {
var pos = getElementPosition(node);
portLabelHoverTimeout = null;
portLabelHover = showTooltip(
(pos[0]),
(pos[1]),
RED._("editor.errors.invalidProperties")+"\n - "+d.validationErrors.join("\n - "),
"top"
);
},500);
}
}
function errorBadgeMouseLeave() {
clearTimeout(portLabelHoverTimeout);
if (portLabelHover) {
portLabelHover.remove();
portLabelHover = null;
}
}
function redrawStatus(d,nodeEl) {
if (d.z !== RED.workspaces.active()) {
return;
@@ -3788,7 +3798,9 @@ RED.view = (function() {
}
var node = nodeLayer.selectAll(".red-ui-flow-node-group").data(activeNodes,function(d){return d.id});
node.exit().remove();
node.exit().each(function(d,i) {
RED.hooks.trigger("viewRemoveNode",{node:d,el:this})
}).remove();
var nodeEnter = node.enter().insert("svg:g")
.attr("class", "red-ui-flow-node red-ui-flow-node-group")
@@ -3935,33 +3947,14 @@ RED.view = (function() {
nodeContents.appendChild(statusEl);
var changeBadgeG = document.createElementNS("http://www.w3.org/2000/svg","g");
changeBadgeG.setAttribute("class","red-ui-flow-node-changed hide");
changeBadgeG.setAttribute("transform","translate(20, -2)");
node[0][0].__changeBadge__ = changeBadgeG;
var changeBadge = document.createElementNS("http://www.w3.org/2000/svg","circle");
changeBadge.setAttribute("r",5);
changeBadgeG.appendChild(changeBadge);
nodeContents.appendChild(changeBadgeG);
var errorBadgeG = document.createElementNS("http://www.w3.org/2000/svg","g");
errorBadgeG.setAttribute("class","red-ui-flow-node-error hide");
errorBadgeG.setAttribute("transform","translate(0, -2)");
node[0][0].__errorBadge__ = errorBadgeG;
var errorBadge = document.createElementNS("http://www.w3.org/2000/svg","path");
errorBadge.setAttribute("d","M -5,4 l 10,0 -5,-8 z");
errorBadgeG.appendChild(errorBadge);
errorBadge.__data__ = d;
errorBadge.addEventListener("mouseenter", errorBadgeMouseEnter);
errorBadge.addEventListener("mouseleave", errorBadgeMouseLeave);
nodeContents.appendChild(errorBadgeG);
node[0][0].appendChild(nodeContents);
RED.hooks.trigger("viewAddNode",{node:d,el:this})
});
node.each(function(d,i) {
if (d.dirty) {
var self = this;
var thisNode = d3.select(this);
var isLink = (d.type === "link in" || d.type === "link out")
@@ -4072,7 +4065,15 @@ RED.view = (function() {
var inputPorts = thisNode.selectAll(".red-ui-flow-port-input");
if ((!isLink || (showAllLinkPorts === -1 && !activeLinkNodes[d.id])) && d.inputs === 0 && !inputPorts.empty()) {
inputPorts.remove();
inputPorts.each(function(d,i) {
RED.hooks.trigger("viewRemovePort",{
node:d,
el:self,
port:d3.select(this)[0][0],
portType: "input",
portIndex: 0
})
}).remove();
} else if (((isLink && (showAllLinkPorts===PORT_TYPE_INPUT||activeLinkNodes[d.id]))|| d.inputs === 1) && inputPorts.empty()) {
var inputGroup = thisNode.append("g").attr("class","red-ui-flow-port-input");
var inputGroupPorts;
@@ -4085,12 +4086,17 @@ RED.view = (function() {
} else {
inputGroupPorts = inputGroup.append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
}
inputGroup[0][0].__port__ = inputGroupPorts[0][0];
inputGroupPorts[0][0].__data__ = this.__data__;
inputGroupPorts[0][0].__portType__ = PORT_TYPE_INPUT;
inputGroupPorts[0][0].__portIndex__ = 0;
inputGroupPorts.on("mousedown",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);})
.on("touchstart",function(d){portMouseDown(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();})
.on("mouseup",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);} )
.on("touchend",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();} )
.on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);})
.on("mouseout",function(d) {portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);});
RED.hooks.trigger("viewAddPort",{node:d,el: this, port: inputGroup[0][0], portType: "input", portIndex: 0})
}
var numOutputs = d.outputs;
if (isLink && d.type === "link out") {
@@ -4105,6 +4111,13 @@ RED.view = (function() {
// Remove extra ports
while (this.__outputs__.length > numOutputs) {
var port = this.__outputs__.pop();
RED.hooks.trigger("viewRemovePort",{
node:d,
el:this,
port:port,
portType: "output",
portIndex: this.__outputs__.length
})
port.remove();
}
for(var portIndex = 0; portIndex < numOutputs; portIndex++ ) {
@@ -4128,6 +4141,7 @@ RED.view = (function() {
portPort.setAttribute("class","red-ui-flow-port");
}
portGroup.appendChild(portPort);
portGroup.__port__ = portPort;
portPort.__data__ = this.__data__;
portPort.__portType__ = PORT_TYPE_OUTPUT;
portPort.__portIndex__ = portIndex;
@@ -4140,6 +4154,7 @@ RED.view = (function() {
this.appendChild(portGroup);
this.__outputs__.push(portGroup);
RED.hooks.trigger("viewAddPort",{node:d,el: this, port: portGroup, portType: "output", portIndex: portIndex})
} else {
portGroup = this.__outputs__[portIndex];
}
@@ -4176,10 +4191,10 @@ RED.view = (function() {
);
faIcon.attr("y",(d.h+13)/2);
}
this.__changeBadge__.setAttribute("transform", "translate("+(d.w-10)+", -2)");
this.__changeBadge__.classList.toggle("hide", !(d.changed||d.moved));
this.__errorBadge__.setAttribute("transform", "translate("+(d.w-10-((d.changed||d.moved)?14:0))+", -2)");
this.__errorBadge__.classList.toggle("hide", d.valid);
// this.__changeBadge__.setAttribute("transform", "translate("+(d.w-10)+", -2)");
// this.__changeBadge__.classList.toggle("hide", !(d.changed||d.moved));
// this.__errorBadge__.setAttribute("transform", "translate("+(d.w-10-((d.changed||d.moved)?14:0))+", -2)");
// this.__errorBadge__.classList.toggle("hide", d.valid);
thisNode.selectAll(".red-ui-flow-port-input").each(function(d,i) {
var port = d3.select(this);
@@ -4242,6 +4257,8 @@ RED.view = (function() {
}
}
}
RED.hooks.trigger("viewRedrawNode",{node:d,el:this})
});
var link = linkLayer.selectAll(".red-ui-flow-link").data(
activeLinks,
@@ -5016,6 +5033,30 @@ RED.view = (function() {
}
return selection;
}
function calculateNodeDimensions(node) {
var result = [node_width,node_height];
try {
var isLink = (node.type === "link in" || node.type === "link out")
var hideLabel = node.hasOwnProperty('l')?!node.l : isLink;
var label = RED.utils.getNodeLabel(node, node.type);
var labelParts = getLabelParts(label, "red-ui-flow-node-label");
if (hideLabel) {
result[1] = Math.max(node_height,(node.outputs || 0) * 15);
} else {
result[1] = Math.max(6+24*labelParts.lines.length,(node.outputs || 0) * 15, 30);
}
if (hideLabel) {
result[0] = node_height;
} else {
result[0] = Math.max(node_width,20*(Math.ceil((labelParts.width+50+(node._def.inputs>0?7:0))/20)) );
}
}catch(err) {
console.log("Error",node);
}
return result;
}
return {
init: init,
state:function(state) {
@@ -5081,6 +5122,9 @@ RED.view = (function() {
return scaleFactor;
},
getLinksAtPoint: function(x,y) {
// x,y must be in SVG co-ordinate space
// if they come from a node.x/y, they will need to be scaled using
// scaleFactor first.
var result = [];
var links = outer.selectAll(".red-ui-flow-link-background")[0];
for (var i=0;i<links.length;i++) {
@@ -5244,6 +5288,9 @@ RED.view = (function() {
return clipboard
},
redrawStatus: redrawStatus,
showQuickAddDialog:showQuickAddDialog
showQuickAddDialog:showQuickAddDialog,
calculateNodeDimensions: calculateNodeDimensions,
getElementPosition:getElementPosition,
showTooltip:showTooltip
};
})();

View File

@@ -493,7 +493,11 @@ RED.workspaces = (function() {
if (!workspace_tabs.contains(id)) {
var sf = RED.nodes.subflow(id);
if (sf) {
addWorkspace({type:"subflow",id:id,icon:"red/images/subflow_tab.svg",label:sf.name, closeable: true});
addWorkspace(
{type:"subflow",id:id,icon:"red/images/subflow_tab.svg",label:sf.name, closeable: true},
null,
workspace_tabs.activeIndex()+1
);
} else {
return;
}

View File

@@ -149,7 +149,7 @@ body {
.red-ui-font-code {
font-family: $monospace-font;
font-size: $primary-font-size;
color: $info-text-code-color;
color: $text-color-code;
white-space: nowrap;
}
@@ -158,7 +158,7 @@ body {
font-size: $primary-font-size;
padding: 0px;
margin: 1px;
color: $info-text-code-color;
color: $text-color-code;
white-space: nowrap;
}

View File

@@ -48,15 +48,22 @@ $tertiary-text-color: #aaa;//#90f;
// Heading text
$header-text-color: #444;//#f00;
$text-color-warning: #AD1625;
$text-color-green: #3a3;
$text-color-error: #AD1625;
$text-color-warning: #CAB200;
$text-color-success: #3a3;
$text-color-code: #AD1625;
$text-color-link: #0088cc;
$primary-border-color: #bbbbbb;//#f00;
$secondary-border-color: #dddddd;//#0f0;
$tertiary-border-color: #ccc;//#00f;
$form-background: $secondary-background;
$border-color-error: #DF2935;
$border-color-warning: #FFCF70;
$border-color-success: #4B8400;
$form-background: $secondary-background;
$form-placeholder-color: $tertiary-text-color;
$form-text-color: $primary-text-color;
$form-text-color-disabled: $secondary-text-color-disabled;
@@ -257,16 +264,13 @@ $headerMenuCaret: #C7C7C7;
$vcCommitShaColor: #c38888;
$info-text-code-color: #AD1625;
$info-text-link-color: #0088cc;
$dnd-background: rgba(0,0,0,0.3);
$dnd-color: #fff;
$notification-border-default: #325C80;
$notification-border-success: #4B8400;
$notification-border-warning: #D74108;
$notification-border-error: $text-color-warning;
$notification-border-success: $border-color-success;
$notification-border-warning: $border-color-warning;
$notification-border-error: $border-color-error;
$debug-message-background: $secondary-background;
$debug-message-background-hover: $secondary-background-selected;
@@ -282,11 +286,16 @@ $debug-message-text-color-msg-type-number: #2033d6;
$debug-message-border: #eee;
$debug-message-border-hover: #999;
$debug-message-border-warning: #ffdf9d;
$debug-message-border-error: #f99;
$debug-message-border-warning: $border-color-warning;
$debug-message-border-error: $border-color-error;
$group-default-fill: none;
$group-default-fill-opacity: 1;
$group-default-stroke: #999;
$group-default-stroke-opacity: 1;
$group-default-label-color: #a4a4a4;
$group-default-label-color: #a4a4a4;
// Deprecated
$text-color-green: $text-color-success;
$info-text-code-color: $text-color-code;
$info-text-link-color: $text-color-link;

View File

@@ -500,7 +500,7 @@ ul.red-ui-deploy-dialog-confirm-list {
width: 30px;
margin-right: 10px;
&.fa-check {
color: $text-color-green;
color: $text-color-success;
}
&.fa-exclamation {
color: $secondary-text-color;

View File

@@ -222,7 +222,7 @@ button.red-ui-tray-resize-button {
}
.form-warning {
border-color: $text-color-warning;
border-color: $text-color-error;
}
}

View File

@@ -255,11 +255,11 @@ g.red-ui-flow-node-selected {
}
}
@each $current-color in red green yellow blue grey gray {
.red-ui-flow-node-status-dot-#{$current-color} {
.red-ui-flow-node-status-dot-#{""+$current-color} {
fill: map-get($node-status-colors,$current-color);
stroke: map-get($node-status-colors,$current-color);
}
.red-ui-flow-node-status-ring-#{$current-color} {
.red-ui-flow-node-status-ring-#{""+$current-color} {
fill: $view-background;
stroke: map-get($node-status-colors,$current-color);
}

View File

@@ -395,6 +395,7 @@
select[readonly],
textarea[readonly] {
cursor: not-allowed;
color: $form-text-color-disabled;
background-color: $form-input-background-disabled;
}

View File

@@ -51,18 +51,17 @@
}
.red-ui-clipboard-dialog-tab-clipboard {
textarea {
resize: none;
width: 100%;
border-radius: 4px;
font-family: $monospace-font !important;
font-size: 13px !important;
height: 100%;
line-height: 1.3em;
padding: 6px 10px;
background: $clipboard-textarea-background;
color: $secondary-text-color-active !important;
resize: none;
width: 100%;
border-radius: 4px;
font-family: $monospace-font !important;
font-size: 13px !important;
height: 100%;
line-height: 1.3em;
padding: 6px 10px;
background: $clipboard-textarea-background;
}
}
@@ -269,4 +268,4 @@
color: $secondary-text-color;
font-size: 0.9em;
}
}
}

View File

@@ -25,7 +25,7 @@
.red-ui-notification {
box-sizing: border-box;
position: relative;
padding: 14px 18px;
padding: 8px 18px 0px;
margin-bottom: 4px;
box-shadow: 0 1px 1px 1px $shadow;
background-color: $secondary-background;
@@ -35,6 +35,7 @@
overflow: hidden;
.ui-dialog-buttonset {
margin-top: 20px;
margin-bottom: 10px;
}
}
.red-ui-notification p:first-child {
@@ -59,13 +60,13 @@
}
.red-ui-notification-compact {
p {
margin: 0;
}
.ui-dialog-buttonset {
button {
line-height: 12px;
}
margin-top: 0;
position: absolute;
top: 8px;
top: 6px;
right: 10px;
}
}

View File

@@ -174,7 +174,7 @@
display: block;
text-align: center;
padding: 12px 8px;
color: $text-color-warning;
color: $text-color-code;
&:hover {
text-decoration: none;

View File

@@ -229,3 +229,90 @@
left: 1px;
}
}
////////////////
.red-ui-node-list-item {
display: inline-block;
padding: 0;
font-size: 13px;
border: none;
}
.red-ui-node-icon {
display: inline-block;
width: 24px;
height: 20px;
line-height: 20px;
margin-top: 1px;
// width: 30px;
// height: 25px;
border-radius: 3px;
border: 1px solid $node-border;
background-position: 5% 50%;
background-repeat: no-repeat;
background-size: contain;
position: relative;
background-color: $node-icon-background-color;
text-align: center;
.red-ui-palette-icon {
width: 20px;
}
.red-ui-palette-icon-fa {
font-size: 14px;
position: relative;
top: -1px;
left: 0px;
}
&.red-ui-palette-icon-flow,
&.red-ui-palette-icon-group,
&.red-ui-palette-icon-selection {
background: none;
border-color: transparent;
.red-ui-palette-icon-container {
background: none;
}
.red-ui-palette-icon-fa {
color: $secondary-text-color;
font-size: 16px;
}
}
}
.red-ui-node-icon-container {
display: inline-flex;
align-items: center;
}
.red-ui-node-icon-container.red-ui-node-icon-small {
.red-ui-node-icon {
width: 18px;
height: 15px;
line-height: 15px;
.red-ui-palette-icon {
width: 15px;
}
.red-ui-palette-icon-fa {
font-size: 11px;
}
.red-ui-icons-flow {
width: 14px;
}
&.red-ui-palette-icon-flow {
margin-top: -2px;
}
&.red-ui-palette-icon-group .red-ui-palette-icon-fa {
font-size: 14px;
}
}
.red-ui-node-label {
}
}
.red-ui-node-label {
white-space: nowrap;
margin-left: 4px;
color: $secondary-text-color;
}

View File

@@ -103,7 +103,7 @@
left: -1px;
}
.red-ui-search-result-description {
margin-left:28px;
margin-left:8px;
}
.red-ui-search-result-node-label {
color: $secondary-text-color;
@@ -133,7 +133,8 @@
}
.red-ui-search-result {
padding: 8px 2px 8px 5px;
display: block;
display: flex;
align-items: start;
cursor: pointer;
color: $list-item-color;
background: $list-item-background;
@@ -156,12 +157,7 @@
display: table;
clear: both;
}
.red-ui-palette-icon-fa {
top: 6px;
left: 3px;
}
}
.red-ui-search-result-node {
display: inline-block;
width: 30px;
@@ -180,8 +176,9 @@
}
.red-ui-search-result-node-description {
margin-left: 40px;
margin-left: 10px;
margin-right: 5px;
flex-grow: 1;
}
.red-ui-search-result-node-label {
color: $primary-text-color;

View File

@@ -46,7 +46,7 @@
right: 315px;
bottom:10px;
width: 7px;
z-index: 11;
// z-index: 11;
background: $primary-background url(images/grip.png) no-repeat 50% 50%;
cursor: col-resize;
}
@@ -134,6 +134,7 @@ button.red-ui-sidebar-header-button-toggle {
right: calc(100%);
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
z-index: 13;
}
.red-ui-sidebar-control-left {
@include red-ui-sidebar-control;

View File

@@ -15,6 +15,7 @@
**/
@import "colors";
@import "variables";
@import "mixins";
@import "base";

View File

@@ -125,13 +125,13 @@ div.red-ui-info-table {
line-height: 1.5em;
a {
color: $info-text-link-color;
color: $text-color-link;
text-decoration: none;
}
a:hover,
a:focus {
color: $info-text-link-color;
color: $text-color-link;
text-decoration: underline;
}
@@ -176,7 +176,7 @@ div.red-ui-info-table {
font-family: $monospace-font;
font-weight: normal;
margin: 5px 3px 1px;
color: $text-color-warning;
color: $text-color-code;
white-space: nowrap;
&.optional {
font-style: italic;
@@ -326,13 +326,17 @@ div.red-ui-info-table {
border-bottom: 1px solid $secondary-border-color;
}
}
.red-ui-info-outline,.red-ui-sidebar-help-toc, #red-ui-clipboard-dialog-import-conflicts-list, #red-ui-clipboard-dialog-export-tab-clipboard-preview {
.red-ui-info-outline,
// TODO: remove these classes for 2.0. Keeping in 1.x for backwards compatibility
// of theme generators.
.red-ui-sidebar-help-toc, #red-ui-clipboard-dialog-import-conflicts-list, #red-ui-clipboard-dialog-export-tab-clipboard-preview
{
.red-ui-info-outline-item {
display: inline-block;
padding: 0;
font-size: 13px;
border: none;
.red-ui-palette-icon-fa {
&:not(.red-ui-node-list-item) .red-ui-palette-icon-fa {
position: relative;
top: 1px;
left: 0px;

View File

@@ -0,0 +1,92 @@
:root {
--red-ui-primary-font: #{$primary-font};
--red-ui-primary-font-size: #{$primary-font-size};
--red-ui-monospace-font: #{$monospace-font};
--red-ui-primary-background: #{$primary-background};
--red-ui-secondary-background: #{$secondary-background};
--red-ui-secondary-background-selected: #{$secondary-background-selected};
--red-ui-secondary-background-inactive: #{$secondary-background-inactive};
--red-ui-secondary-background-hover: #{$secondary-background-hover};
--red-ui-secondary-background-disabled: #{$secondary-background-disabled};
--red-ui-tertiary-background: #{$tertiary-background};
--red-ui-shadow: #{$shadow};
// Main body text
--red-ui-primary-text-color: #{$primary-text-color};
// UI control label text
--red-ui-secondary-text-color: #{$secondary-text-color};
--red-ui-secondary-text-color-focus: #{$secondary-text-color-focus};
--red-ui-secondary-text-color-hover: #{$secondary-text-color-hover};
--red-ui-secondary-text-color-active: #{$secondary-text-color-active};
--red-ui-secondary-text-color-selected: #{$secondary-text-color-selected};
--red-ui-secondary-text-color-inactive: #{$secondary-text-color-inactive};
--red-ui-secondary-text-color-disabled: #{$secondary-text-color-disabled};
--red-ui-secondary-text-color-disabled-active: #{$secondary-text-color-disabled-active};
--red-ui-secondary-text-color-disabled-inactive: #{$secondary-text-color-disabled-inactive};
// Sub label text
--red-ui-tertiary-text-color: #{$tertiary-text-color};
// Heading text
--red-ui-header-text-color: #{$header-text-color};
--red-ui-text-color-error: #{$text-color-error};
--red-ui-text-color-warning: #{$text-color-warning};
--red-ui-text-color-success: #{$text-color-success};
--red-ui-text-color-code: #{$text-color-code};
--red-ui-text-color-link: #{$text-color-link};
--red-ui-primary-border-color: #{$primary-border-color};
--red-ui-secondary-border-color: #{$secondary-border-color};
--red-ui-tertiary-border-color: #{$tertiary-border-color};
--red-ui-border-color-error: #{$border-color-error};
--red-ui-border-color-warning: #{$border-color-warning};
--red-ui-border-color-success: #{$border-color-success};
--red-ui-form-background: #{$form-background};
--red-ui-form-placeholder-color: #{$form-placeholder-color};
--red-ui-form-text-color: #{$form-text-color};
--red-ui-form-text-color-disabled: #{$form-text-color-disabled};
--red-ui-form-input-border-color: #{$form-input-border-color};
--red-ui-form-input-border-color-focus: #{$form-input-focus-color};
--red-ui-form-input-border-color-selected: #{$form-input-border-selected-color};
--red-ui-form-input-border-color-error: #{$form-input-border-error-color};
--red-ui-form-input-background: #{$form-input-background};
--red-ui-form-input-background-disabled: #{$form-input-background-disabled};
--red-ui-form-button-background: #{$form-button-background};
--red-ui-form-tips-background: #{$form-tips-background};
--red-ui-list-item-color: #{$list-item-color};
--red-ui-list-item-secondary-color: #{$list-item-secondary-color};
--red-ui-list-item-background: #{$list-item-background};
--red-ui-list-item-background-disabled: #{$list-item-background-disabled};
--red-ui-list-item-background-hover: #{$list-item-background-hover};
--red-ui-list-item-background-selected: #{$list-item-background-selected};
--red-ui-list-item-border-selected: #{$list-item-border-selected};
--red-ui-shade-color: #{$shade-color};
--red-ui-node-link-port-background: #{$node-link-port-background};
--red-ui-node-status-error-border: #{$node-status-error-border};
--red-ui-node-status-error-background: #{$node-status-error-background};
--red-ui-node-status-changed-border: #{$node-status-changed-border};
--red-ui-node-status-changed-background: #{$node-status-changed-background};
--red-ui-node-border: #{$node-border};
--red-ui-node-port-background:#{$node-port-background};
--red-ui-node-label-color: #{$node-label-color};
--red-ui-node-selected-color: #{$node-selected-color};
--red-ui-port-selected-color: #{$port-selected-color};
}

View File

@@ -0,0 +1,39 @@
node and node-red types for intellisense for monaco
---------------------------------------------------
node-js and node-red types are included in node-red for monaco and any other editor to provide intellisense in the code editor
as node-js v14 is the default recommended target as of writing, the most popular node-js types (see below) have been taken from most up-to-date types from `@types/node` and minified using `dts-minify`
* buffer.d.ts
* console.d.ts
* crypto.d.ts
* fs.d.ts
* globals.d.ts
* http.d.ts
* net.d.ts
* os.d.ts
* process.d.ts
* querystring.d.ts
* string_decoder.d.ts
* url.d.ts
* zlib.d.ts
These are placed in `node_modules/@node-red/editor-client/src/`
The grunt task will place this default set of typings in `node_modules/@node-red/editor-client/public/types/` for consumption by the code editor.
# Instructions
See packages/node_modules/@node-red/editor-client/src/vendor/monaco/README.md
# Alternative / Manual Installation
* `npm install --save @types/node@14.14.43`
* (optional) minify using `dts-minify`
* copy files from `node_modules/@node-red/editor-client/src/` to `(node-red-src)/packages/node_modules/@node-red/editor-client/src/types/node`
* update types for node-red in files to match src definitions...
* (node-red-src)/packages/node_modules/@node-red/editor-client/src/types/node-red/func.d.ts
* (node-red-src)/packages/node_modules/@node-red/editor-client/src/types/node-red/util.d.ts

View File

@@ -0,0 +1,266 @@
/* NOTE: Do not edit directly! This file is generated using \`npm run update-types\` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
interface NodeMessage {
topic?: string;
payload?: any;
_msgid?: string;
[other: string]: any; //permit other properties
}
/** @type {NodeMessage} the `msg` object */
declare var msg: NodeMessage;
/** @type {string} the id of the incoming `msg` (alias of msg._msgid) */
declare const __msgid__:string;
/**
* @typedef NodeStatus
* @type {object}
* @property {string} [fill] The fill property can be: red, green, yellow, blue or grey.
* @property {string} [shape] The shape property can be: ring or dot.
* @property {string} [text] The text to display
*/
interface NodeStatus {
/** The fill property can be: red, green, yellow, blue or grey */
fill?: string,
/** The shape property can be: ring or dot */
shape?: string,
/** The text to display */
text?: string|boolean|number
}
declare class node {
/**
* Send 1 or more messages asynchronously
* @param {object | object[]} msg The msg object
* @param {Boolean} [clone=true] Flag to indicate the `msg` should be cloned. Default = `true`
* @see node-red documentation [writing-functions: sending messages asynchronously](https://nodered.org/docs/user-guide/writing-functions#sending-messages-asynchronously)
*/
static send(msg:object|object[], clone?:Boolean): void;
/** Inform runtime this instance has completed its operation */
static done();
/** Send an error to the console and debug side bar. Include `msg` in the 2nd parameter to trigger the catch node. */
static error(err:string|Error, msg?:object);
/** Log a warn message to the console and debug sidebar */
static warn(warning:string|object);
/** Log an info message to the console (not sent to sidebar)' */
static log(info:string|object);
/** Sets the status icon and text underneath the node.
* @param {NodeStatus} status - The status object `{fill, shape, text}`
* @see node-red documentation [writing-functions: adding-status](https://nodered.org/docs/user-guide/writing-functions#adding-status)
*/
static status(status:NodeStatus);
/** Sets the status text underneath the node.
* @param {string} status - The status to display
* @see node-red documentation [writing-functions: adding-status](https://nodered.org/docs/user-guide/writing-functions#adding-status)
*/
static status(status:string|boolean|number);
/** the id of this node */
public readonly id:string;
/** the name of this node */
public readonly name:string;
/** the number of outputs of this node */
public readonly outputCount:number;
}
declare class context {
/**
* Get one or multiple values from context (synchronous).
* @param name - Name of context variable
*/
static get(name: string | string[]);
/**
* Get one or multiple values from context (asynchronous).
* @param name - Name (or array of names) to get from context
* @param {function} callback - (optional) Callback function (`(err,value) => {}`)
*/
static get(name: string | string[], callback: Function);
/**
* Get one or multiple values from context (synchronous).
* @param name - Name (or array of names) to get from context
* @param store - Name of context store
*/
static get(name: string | string[], store: string);
/**
* Get one or multiple values from context (asynchronous).
* @param name - Name (or array of names) to get from context
* @param store - Name of context store
* @param {function} callback - (optional) Callback function (`(err,value) => {}`)
*/
static get(name: string | string[], store: string, callback: Function);
/**
* Set one or multiple values in context (synchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
*/
static set(name: string | string[], value?: any | any[]);
/**
* Set one or multiple values in context (asynchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
* @param callback - (optional) Callback function (`(err) => {}`)
*/
static set(name: string | string[], value?: any | any[], callback?: Function);
/**
* Set one or multiple values in context (synchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
* @param store - (optional) Name of context store
*/
static set(name: string | string[], value?: any | any[], store?: string);
/**
* Set one or multiple values in context (asynchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
* @param store - (optional) Name of context store
* @param callback - (optional) Callback function (`(err) => {}`)
*/
static set(name: string | string[], value?: any | any[], store?: string, callback?: Function);
/** Get an array of the keys in the context store */
static keys(): Array<string>;
/** Get an array of the keys in the context store */
static keys(store: string): Array<string>;
/** Get an array of the keys in the context store */
static keys(callback: Function);
/** Get an array of the keys in the context store */
static keys(store: string, callback: Function);
}
declare class flow {
/**
* Get one or multiple values from context (synchronous).
* @param name - Name of context variable
*/
static get(name: string | string[]);
/**
* Get one or multiple values from context (asynchronous).
* @param name - Name (or array of names) to get from context
* @param {function} callback - (optional) Callback function (`(err,value) => {}`)
*/
static get(name: string | string[], callback: Function);
/**
* Get one or multiple values from context (synchronous).
* @param name - Name (or array of names) to get from context
* @param store - Name of context store
*/
static get(name: string | string[], store: string);
/**
* Get one or multiple values from context (asynchronous).
* @param name - Name (or array of names) to get from context
* @param store - Name of context store
* @param {function} callback - (optional) Callback function (`(err,value) => {}`)
*/
static get(name: string | string[], store: string, callback: Function);
/**
* Set one or multiple values in context (synchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
*/
static set(name: string | string[], value?: any | any[]);
/**
* Set one or multiple values in context (asynchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
* @param callback - (optional) Callback function (`(err) => {}`)
*/
static set(name: string | string[], value?: any | any[], callback?: Function);
/**
* Set one or multiple values in context (synchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
* @param store - (optional) Name of context store
*/
static set(name: string | string[], value?: any | any[], store?: string);
/**
* Set one or multiple values in context (asynchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
* @param store - (optional) Name of context store
* @param callback - (optional) Callback function (`(err) => {}`)
*/
static set(name: string | string[], value?: any | any[], store?: string, callback?: Function);
/** Get an array of the keys in the context store */
static keys(): Array<string>;
/** Get an array of the keys in the context store */
static keys(store: string): Array<string>;
/** Get an array of the keys in the context store */
static keys(callback: Function);
/** Get an array of the keys in the context store */
static keys(store: string, callback: Function);
}
// @ts-ignore
declare class global {
/**
* Get one or multiple values from context (synchronous).
* @param name - Name of context variable
*/
static get(name: string | string[]);
/**
* Get one or multiple values from context (asynchronous).
* @param name - Name (or array of names) to get from context
* @param {function} callback - (optional) Callback function (`(err,value) => {}`)
*/
static get(name: string | string[], callback: Function);
/**
* Get one or multiple values from context (synchronous).
* @param name - Name (or array of names) to get from context
* @param store - Name of context store
*/
static get(name: string | string[], store: string);
/**
* Get one or multiple values from context (asynchronous).
* @param name - Name (or array of names) to get from context
* @param store - Name of context store
* @param {function} callback - (optional) Callback function (`(err,value) => {}`)
*/
static get(name: string | string[], store: string, callback: Function);
/**
* Set one or multiple values in context (synchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
*/
static set(name: string | string[], value?: any | any[]);
/**
* Set one or multiple values in context (asynchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
* @param callback - (optional) Callback function (`(err) => {}`)
*/
static set(name: string | string[], value?: any | any[], callback?: Function);
/**
* Set one or multiple values in context (synchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
* @param store - (optional) Name of context store
*/
static set(name: string | string[], value?: any | any[], store?: string);
/**
* Set one or multiple values in context (asynchronous).
* @param name - Name (or array of names) to set in context
* @param value - The value (or array of values) to store in context. If the value(s) are null/undefined, the context item(s) will be removed.
* @param store - (optional) Name of context store
* @param callback - (optional) Callback function (`(err) => {}`)
*/
static set(name: string | string[], value?: any | any[], store?: string, callback?: Function);
/** Get an array of the keys in the context store */
static keys(): Array<string>;
/** Get an array of the keys in the context store */
static keys(store: string): Array<string>;
/** Get an array of the keys in the context store */
static keys(callback: Function);
/** Get an array of the keys in the context store */
static keys(store: string, callback: Function);
}
declare class env {
/** Get an environment variable value */
static get(name:string);
}

View File

@@ -0,0 +1,211 @@
/* NOTE: Do not edit directly! This file is generated using \`npm run update-types\` in https://github.com/Steve-Mcl/monaco-editor-esm-i18n */
/*
How to generate...
1. Generate from packages\node_modules\@node-red\util\lib\util.js using `npx typescript` and a tsconfig.json of...
{
"files": ["packages/node_modules/@node-red/util/lib/util.js"],
"compilerOptions": {
"allowJs": true,
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "types",
"strict": false,
"moduleResolution": "node"
}
}
2. remove all the `export ` statements
3. Wrap the remaining code in declare namespace RED { declare namespace util { ... } }
4. check . adjust types like String --> string, Object --> object etc (where appropriate)
*/
declare namespace RED {
/**
* Utility functions for the node-red function sandbox
*/
namespace util {
/**
* Encode an object to JSON without losing information about non-JSON types
* such as Buffer and Function.
*
* *This function is closely tied to its reverse within the editor*
*
* @param {Object} msg
* @param {Object} opts
* @return {Object} the encoded object
* @memberof @node-red/util_util
*/
function encodeObject(msg: any, opts: any): any;
/**
* Converts the provided argument to a String, using type-dependent
* methods.
*
* @param {any} o - the property to convert to a String
* @return {string} the stringified version
* @memberof @node-red/util_util
*/
function ensureString(o: any): string;
/**
* Converts the provided argument to a Buffer, using type-dependent
* methods.
*
* @param {any} o - the property to convert to a Buffer
* @return {string} the Buffer version
* @memberof @node-red/util_util
*/
function ensureBuffer(o: any): string;
/**
* Safely clones a message object. This handles msg.req/msg.res objects that must
* not be cloned.
*
* @param {object} msg - the message object to clone
* @return {object} the cloned message
* @memberof @node-red/util_util
*/
function cloneMessage(msg: object): object;
/**
* Compares two objects, handling various JavaScript types.
*
* @param {any} obj1
* @param {any} obj2
* @return {boolean} whether the two objects are the same
* @memberof @node-red/util_util
*/
function compareObjects(obj1: any, obj2: any): boolean;
/**
* Generates a psuedo-unique-random id.
* @return {string} a random-ish id
* @memberof @node-red/util_util
*/
function generateId(): string;
/**
* Gets a property of a message object.
*
* Unlike {@link @node-red/util-util.getObjectProperty}, this function will strip `msg.` from the
* front of the property expression if present.
*
* @param {object} msg - the message object
* @param {string} expr - the property expression
* @return {any} the message property, or undefined if it does not exist
* @throws Will throw an error if the *parent* of the property does not exist
* @memberof @node-red/util_util
*/
function getMessageProperty(msg: object, expr: string): any;
/**
* Sets a property of a message object.
*
* Unlike {@link @node-red/util-util.setObjectProperty}, this function will strip `msg.` from the
* front of the property expression if present.
*
* @param {object} msg - the message object
* @param {string} prop - the property expression
* @param {any} [value] - the value to set
* @param {boolean} [createMissing] - whether to create missing parent properties
* @memberof @node-red/util_util
*/
function setMessageProperty(msg: object, prop: string, value?: any, createMissing?: boolean): boolean;
/**
* Gets a property of an object.
*
* Given the object:
*
* {
* "pet": {
* "type": "cat"
* }
* }
*
* - `pet.type` will return `"cat"`.
* - `pet.name` will return `undefined`
* - `car` will return `undefined`
* - `car.type` will throw an Error (as `car` does not exist)
*
* @param {object} msg - the object
* @param {string} expr - the property expression
* @return {any} the object property, or undefined if it does not exist
* @throws Will throw an error if the *parent* of the property does not exist
* @memberof @node-red/util_util
*/
function getObjectProperty(msg: object, expr: string): any;
/**
* Sets a property of an object.
*
* @param {object} msg - the object
* @param {string} prop - the property expression
* @param {any} [value] - the value to set
* @param {boolean} [createMissing] - whether to create missing parent properties
* @memberof @node-red/util_util
*/
function setObjectProperty(msg: object, prop: string, value?: any, createMissing?: boolean): boolean;
/**
* Evaluates a property value according to its type.
*
* @param {string} value - the raw value
* @param {string} type - the type of the value
* @param {Node} node - the node evaluating the property
* @param {Object} msg - the message object to evaluate against
* @param {Function} callback - (optional) called when the property is evaluated
* @return {any} The evaluated property, if no `callback` is provided
* @memberof @node-red/util_util
*/
function evaluateNodeProperty(value: string, type: string, node: Node, msg: any, callback: Function): any;
/**
* Parses a property expression, such as `msg.foo.bar[3]` to validate it
* and convert it to a canonical version expressed as an Array of property
* names.
*
* For example, `a["b"].c` returns `['a','b','c']`
*
* @param {string} str - the property expression
* @return {any[]} the normalised expression
* @memberof @node-red/util_util
*/
function normalisePropertyExpression(str: string): any[];
/**
* Normalise a node type name to camel case.
*
* For example: `a-random node type` will normalise to `aRandomNodeType`
*
* @param {string} name - the node type
* @return {string} The normalised name
* @memberof @node-red/util_util
*/
function normaliseNodeTypeName(name: string): string;
/**
* Prepares a JSONata expression for evaluation.
* This attaches Node-RED specific functions to the expression.
*
* @param {string} value - the JSONata expression
* @param {Node} node - the node evaluating the property
* @return {any} The JSONata expression that can be evaluated
* @memberof @node-red/util_util
*/
function prepareJSONataExpression(value: string, node: Node): any;
/**
* Evaluates a JSONata expression.
* The expression must have been prepared with {@link @node-red/util-util.prepareJSONataExpression}
* before passing to this function.
*
* @param {Object} expr - the prepared JSONata expression
* @param {Object} msg - the message object to evaluate against
* @param {Function} callback - (optional) called when the expression is evaluated
* @return {any} If no callback was provided, the result of the expression
* @memberof @node-red/util_util
*/
function evaluateJSONataExpression(expr: any, msg: any, callback: Function): any;
/**
* Parses a context property string, as generated by the TypedInput, to extract
* the store name if present.
*
* For example, `#:(file)::foo` results in ` { store: "file", key: "foo" }`.
*
* @param {string} key - the context property string to parse
* @return {any} The parsed property
* @memberof @node-red/util_util
*/
function parseContextStore(key: string): any;
}
}

View File

@@ -0,0 +1 @@
declare module'node:buffer'{export*from'buffer';}declare module'buffer'{export const INSPECT_MAX_BYTES:number;export const kMaxLength:number;export const kStringMaxLength:number;export const constants:{MAX_LENGTH:number;MAX_STRING_LENGTH:number;};const BuffType:typeof Buffer;export type TranscodeEncoding="ascii"|"utf8"|"utf16le"|"ucs2"|"latin1"|"binary";export function transcode(source:Uint8Array,fromEnc:TranscodeEncoding,toEnc:TranscodeEncoding):Buffer;export const SlowBuffer:{new(size:number):Buffer;prototype:Buffer;};export{BuffType as Buffer};}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
declare module'node:console'{export=console;}declare module'console'{import{InspectOptions}from'node:util';global{interface Console{Console:NodeJS.ConsoleConstructor;assert(value:any,message?:string,...optionalParams:any[]):void;clear():void;count(label?:string):void;countReset(label?:string):void;debug(message?:any,...optionalParams:any[]):void;dir(obj:any,options?:InspectOptions):void;dirxml(...data:any[]):void;error(message?:any,...optionalParams:any[]):void;group(...label:any[]):void;groupCollapsed(...label:any[]):void;groupEnd():void;info(message?:any,...optionalParams:any[]):void;log(message?:any,...optionalParams:any[]):void;table(tabularData:any,properties?:ReadonlyArray<string>):void;time(label?:string):void;timeEnd(label?:string):void;timeLog(label?:string,...data:any[]):void;trace(message?:any,...optionalParams:any[]):void;warn(message?:any,...optionalParams:any[]):void;profile(label?:string):void;profileEnd(label?:string):void;timeStamp(label?:string):void;}var console:Console;namespace NodeJS{interface ConsoleConstructorOptions{stdout:WritableStream;stderr?:WritableStream;ignoreErrors?:boolean;colorMode?:boolean|'auto';inspectOptions?:InspectOptions;}interface ConsoleConstructor{prototype:Console;new(stdout:WritableStream,stderr?:WritableStream,ignoreErrors?:boolean):Console;new(options:ConsoleConstructorOptions):Console;}interface Global{console:typeof console;}}}export=console;}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
declare module'node:dgram'{export*from'dgram';}declare module'dgram'{import{AddressInfo}from'node:net';import*as dns from'node:dns';import EventEmitter=require('node:events');interface RemoteInfo{address:string;family:'IPv4'|'IPv6';port:number;size:number;}interface BindOptions{port?:number;address?:string;exclusive?:boolean;fd?:number;}type SocketType="udp4"|"udp6";interface SocketOptions{type:SocketType;reuseAddr?:boolean;ipv6Only?:boolean;recvBufferSize?:number;sendBufferSize?:number;lookup?:(hostname:string,options:dns.LookupOneOptions,callback:(err:NodeJS.ErrnoException|null,address:string,family:number)=>void)=>void;}function createSocket(type:SocketType,callback?:(msg:Buffer,rinfo:RemoteInfo)=>void):Socket;function createSocket(options:SocketOptions,callback?:(msg:Buffer,rinfo:RemoteInfo)=>void):Socket;class Socket extends EventEmitter{addMembership(multicastAddress:string,multicastInterface?:string):void;address():AddressInfo;bind(port?:number,address?:string,callback?:()=>void):void;bind(port?:number,callback?:()=>void):void;bind(callback?:()=>void):void;bind(options:BindOptions,callback?:()=>void):void;close(callback?:()=>void):void;connect(port:number,address?:string,callback?:()=>void):void;connect(port:number,callback:()=>void):void;disconnect():void;dropMembership(multicastAddress:string,multicastInterface?:string):void;getRecvBufferSize():number;getSendBufferSize():number;ref():this;remoteAddress():AddressInfo;send(msg:string|Uint8Array|ReadonlyArray<any>,port?:number,address?:string,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array|ReadonlyArray<any>,port?:number,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array|ReadonlyArray<any>,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array,offset:number,length:number,port?:number,address?:string,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array,offset:number,length:number,port?:number,callback?:(error:Error|null,bytes:number)=>void):void;send(msg:string|Uint8Array,offset:number,length:number,callback?:(error:Error|null,bytes:number)=>void):void;setBroadcast(flag:boolean):void;setMulticastInterface(multicastInterface:string):void;setMulticastLoopback(flag:boolean):void;setMulticastTTL(ttl:number):void;setRecvBufferSize(size:number):void;setSendBufferSize(size:number):void;setTTL(ttl:number):void;unref():this;addSourceSpecificMembership(sourceAddress:string,groupAddress:string,multicastInterface?:string):void;dropSourceSpecificMembership(sourceAddress:string,groupAddress:string,multicastInterface?:string):void;addListener(event:string,listener:(...args:any[])=>void):this;addListener(event:"close",listener:()=>void):this;addListener(event:"connect",listener:()=>void):this;addListener(event:"error",listener:(err:Error)=>void):this;addListener(event:"listening",listener:()=>void):this;addListener(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;emit(event:string|symbol,...args:any[]):boolean;emit(event:"close"):boolean;emit(event:"connect"):boolean;emit(event:"error",err:Error):boolean;emit(event:"listening"):boolean;emit(event:"message",msg:Buffer,rinfo:RemoteInfo):boolean;on(event:string,listener:(...args:any[])=>void):this;on(event:"close",listener:()=>void):this;on(event:"connect",listener:()=>void):this;on(event:"error",listener:(err:Error)=>void):this;on(event:"listening",listener:()=>void):this;on(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;once(event:string,listener:(...args:any[])=>void):this;once(event:"close",listener:()=>void):this;once(event:"connect",listener:()=>void):this;once(event:"error",listener:(err:Error)=>void):this;once(event:"listening",listener:()=>void):this;once(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;prependListener(event:string,listener:(...args:any[])=>void):this;prependListener(event:"close",listener:()=>void):this;prependListener(event:"connect",listener:()=>void):this;prependListener(event:"error",listener:(err:Error)=>void):this;prependListener(event:"listening",listener:()=>void):this;prependListener(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;prependOnceListener(event:string,listener:(...args:any[])=>void):this;prependOnceListener(event:"close",listener:()=>void):this;prependOnceListener(event:"connect",listener:()=>void):this;prependOnceListener(event:"error",listener:(err:Error)=>void):this;prependOnceListener(event:"listening",listener:()=>void):this;prependOnceListener(event:"message",listener:(msg:Buffer,rinfo:RemoteInfo)=>void):this;}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
declare module'node:domain'{export*from'domain';}declare module'domain'{import EventEmitter=require('node:events');global{namespace NodeJS{interface Domain extends EventEmitter{run<T>(fn:(...args:any[])=>T,...args:any[]):T;add(emitter:EventEmitter|Timer):void;remove(emitter:EventEmitter|Timer):void;bind<T extends Function>(cb:T):T;intercept<T extends Function>(cb:T):T;}}}interface Domain extends NodeJS.Domain{}class Domain extends EventEmitter{members:Array<EventEmitter|NodeJS.Timer>;enter():void;exit():void;}function create():Domain;}

View File

@@ -0,0 +1 @@
declare module'node:events'{import EventEmitter=require('events');export=EventEmitter;}declare module'events'{interface EventEmitterOptions{captureRejections?:boolean;}interface NodeEventTarget{once(event:string|symbol,listener:(...args:any[])=>void):this;}interface DOMEventTarget{addEventListener(event:string,listener:(...args:any[])=>void,opts?:{once:boolean}):any;}interface EventEmitter extends NodeJS.EventEmitter{}class EventEmitter{constructor(options?:EventEmitterOptions);static once(emitter:NodeEventTarget,event:string|symbol):Promise<any[]>;static once(emitter:DOMEventTarget,event:string):Promise<any[]>;static on(emitter:NodeJS.EventEmitter,event:string):AsyncIterableIterator<any>;static listenerCount(emitter:NodeJS.EventEmitter,event:string|symbol):number;static readonly errorMonitor:unique symbol;static readonly captureRejectionSymbol:unique symbol;static captureRejections:boolean;static defaultMaxListeners:number;}import internal=require('events');namespace EventEmitter{export{internal as EventEmitter};}global{namespace NodeJS{interface EventEmitter{addListener(event:string|symbol,listener:(...args:any[])=>void):this;on(event:string|symbol,listener:(...args:any[])=>void):this;once(event:string|symbol,listener:(...args:any[])=>void):this;removeListener(event:string|symbol,listener:(...args:any[])=>void):this;off(event:string|symbol,listener:(...args:any[])=>void):this;removeAllListeners(event?:string|symbol):this;setMaxListeners(n:number):this;getMaxListeners():number;listeners(event:string|symbol):Function[];rawListeners(event:string|symbol):Function[];emit(event:string|symbol,...args:any[]):boolean;listenerCount(event:string|symbol):number;prependListener(event:string|symbol,listener:(...args:any[])=>void):this;prependOnceListener(event:string|symbol,listener:(...args:any[])=>void):this;eventNames():Array<string|symbol>;}}}export=EventEmitter;}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
declare module'node:os'{export*from'os';}declare module'os'{interface CpuInfo{model:string;speed:number;times:{user:number;nice:number;sys:number;idle:number;irq:number;};}interface NetworkInterfaceBase{address:string;netmask:string;mac:string;internal:boolean;cidr:string|null;}interface NetworkInterfaceInfoIPv4 extends NetworkInterfaceBase{family:"IPv4";}interface NetworkInterfaceInfoIPv6 extends NetworkInterfaceBase{family:"IPv6";scopeid:number;}interface UserInfo<T>{username:T;uid:number;gid:number;shell:T;homedir:T;}type NetworkInterfaceInfo=NetworkInterfaceInfoIPv4|NetworkInterfaceInfoIPv6;function hostname():string;function loadavg():number[];function uptime():number;function freemem():number;function totalmem():number;function cpus():CpuInfo[];function type():string;function release():string;function networkInterfaces():NodeJS.Dict<NetworkInterfaceInfo[]>;function homedir():string;function userInfo(options:{encoding:'buffer'}):UserInfo<Buffer>;function userInfo(options?:{encoding:BufferEncoding}):UserInfo<string>;type SignalConstants={[key in NodeJS.Signals]:number;};namespace constants{const UV_UDP_REUSEADDR:number;namespace signals{}const signals:SignalConstants;namespace errno{const E2BIG:number;const EACCES:number;const EADDRINUSE:number;const EADDRNOTAVAIL:number;const EAFNOSUPPORT:number;const EAGAIN:number;const EALREADY:number;const EBADF:number;const EBADMSG:number;const EBUSY:number;const ECANCELED:number;const ECHILD:number;const ECONNABORTED:number;const ECONNREFUSED:number;const ECONNRESET:number;const EDEADLK:number;const EDESTADDRREQ:number;const EDOM:number;const EDQUOT:number;const EEXIST:number;const EFAULT:number;const EFBIG:number;const EHOSTUNREACH:number;const EIDRM:number;const EILSEQ:number;const EINPROGRESS:number;const EINTR:number;const EINVAL:number;const EIO:number;const EISCONN:number;const EISDIR:number;const ELOOP:number;const EMFILE:number;const EMLINK:number;const EMSGSIZE:number;const EMULTIHOP:number;const ENAMETOOLONG:number;const ENETDOWN:number;const ENETRESET:number;const ENETUNREACH:number;const ENFILE:number;const ENOBUFS:number;const ENODATA:number;const ENODEV:number;const ENOENT:number;const ENOEXEC:number;const ENOLCK:number;const ENOLINK:number;const ENOMEM:number;const ENOMSG:number;const ENOPROTOOPT:number;const ENOSPC:number;const ENOSR:number;const ENOSTR:number;const ENOSYS:number;const ENOTCONN:number;const ENOTDIR:number;const ENOTEMPTY:number;const ENOTSOCK:number;const ENOTSUP:number;const ENOTTY:number;const ENXIO:number;const EOPNOTSUPP:number;const EOVERFLOW:number;const EPERM:number;const EPIPE:number;const EPROTO:number;const EPROTONOSUPPORT:number;const EPROTOTYPE:number;const ERANGE:number;const EROFS:number;const ESPIPE:number;const ESRCH:number;const ESTALE:number;const ETIME:number;const ETIMEDOUT:number;const ETXTBSY:number;const EWOULDBLOCK:number;const EXDEV:number;const WSAEINTR:number;const WSAEBADF:number;const WSAEACCES:number;const WSAEFAULT:number;const WSAEINVAL:number;const WSAEMFILE:number;const WSAEWOULDBLOCK:number;const WSAEINPROGRESS:number;const WSAEALREADY:number;const WSAENOTSOCK:number;const WSAEDESTADDRREQ:number;const WSAEMSGSIZE:number;const WSAEPROTOTYPE:number;const WSAENOPROTOOPT:number;const WSAEPROTONOSUPPORT:number;const WSAESOCKTNOSUPPORT:number;const WSAEOPNOTSUPP:number;const WSAEPFNOSUPPORT:number;const WSAEAFNOSUPPORT:number;const WSAEADDRINUSE:number;const WSAEADDRNOTAVAIL:number;const WSAENETDOWN:number;const WSAENETUNREACH:number;const WSAENETRESET:number;const WSAECONNABORTED:number;const WSAECONNRESET:number;const WSAENOBUFS:number;const WSAEISCONN:number;const WSAENOTCONN:number;const WSAESHUTDOWN:number;const WSAETOOMANYREFS:number;const WSAETIMEDOUT:number;const WSAECONNREFUSED:number;const WSAELOOP:number;const WSAENAMETOOLONG:number;const WSAEHOSTDOWN:number;const WSAEHOSTUNREACH:number;const WSAENOTEMPTY:number;const WSAEPROCLIM:number;const WSAEUSERS:number;const WSAEDQUOT:number;const WSAESTALE:number;const WSAEREMOTE:number;const WSASYSNOTREADY:number;const WSAVERNOTSUPPORTED:number;const WSANOTINITIALISED:number;const WSAEDISCON:number;const WSAENOMORE:number;const WSAECANCELLED:number;const WSAEINVALIDPROCTABLE:number;const WSAEINVALIDPROVIDER:number;const WSAEPROVIDERFAILEDINIT:number;const WSASYSCALLFAILURE:number;const WSASERVICE_NOT_FOUND:number;const WSATYPE_NOT_FOUND:number;const WSA_E_NO_MORE:number;const WSA_E_CANCELLED:number;const WSAEREFUSED:number;}namespace priority{const PRIORITY_LOW:number;const PRIORITY_BELOW_NORMAL:number;const PRIORITY_NORMAL:number;const PRIORITY_ABOVE_NORMAL:number;const PRIORITY_HIGH:number;const PRIORITY_HIGHEST:number;}}function arch():string;function version():string;function platform():NodeJS.Platform;function tmpdir():string;const EOL:string;function endianness():"BE"|"LE";function getPriority(pid?:number):number;function setPriority(priority:number):void;function setPriority(pid:number,priority:number):void;}

View File

@@ -0,0 +1 @@
declare module'node:path'{import path=require('path');export=path;}declare module'path'{namespace path{interface ParsedPath{root:string;dir:string;base:string;ext:string;name:string;}interface FormatInputPathObject{root?:string;dir?:string;base?:string;ext?:string;name?:string;}interface PlatformPath{normalize(p:string):string;join(...paths:string[]):string;resolve(...pathSegments:string[]):string;isAbsolute(p:string):boolean;relative(from:string,to:string):string;dirname(p:string):string;basename(p:string,ext?:string):string;extname(p:string):string;readonly sep:string;readonly delimiter:string;parse(p:string):ParsedPath;format(pP:FormatInputPathObject):string;toNamespacedPath(path:string):string;readonly posix:PlatformPath;readonly win32:PlatformPath;}}const path:path.PlatformPath;export=path;}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
declare module'node:querystring'{export*from'querystring';}declare module'querystring'{interface StringifyOptions{encodeURIComponent?:(str:string)=>string;}interface ParseOptions{maxKeys?:number;decodeURIComponent?:(str:string)=>string;}interface ParsedUrlQuery extends NodeJS.Dict<string|string[]>{}interface ParsedUrlQueryInput extends NodeJS.Dict<string|number|boolean|ReadonlyArray<string>|ReadonlyArray<number>|ReadonlyArray<boolean>|null>{}function stringify(obj?:ParsedUrlQueryInput,sep?:string,eq?:string,options?:StringifyOptions):string;function parse(str:string,sep?:string,eq?:string,options?:ParseOptions):ParsedUrlQuery;const encode:typeof stringify;const decode:typeof parse;function escape(str:string):string;function unescape(str:string):string;}

View File

@@ -0,0 +1 @@
declare module'node:url'{export*from'url';}declare module'url'{import{ParsedUrlQuery,ParsedUrlQueryInput}from'node:querystring';interface UrlObject{auth?:string|null;hash?:string|null;host?:string|null;hostname?:string|null;href?:string|null;pathname?:string|null;protocol?:string|null;search?:string|null;slashes?:boolean|null;port?:string|number|null;query?:string|null|ParsedUrlQueryInput;}interface Url{auth:string|null;hash:string|null;host:string|null;hostname:string|null;href:string;path:string|null;pathname:string|null;protocol:string|null;search:string|null;slashes:boolean|null;port:string|null;query:string|null|ParsedUrlQuery;}interface UrlWithParsedQuery extends Url{query:ParsedUrlQuery;}interface UrlWithStringQuery extends Url{query:string|null;}function parse(urlStr:string):UrlWithStringQuery;function parse(urlStr:string,parseQueryString:false|undefined,slashesDenoteHost?:boolean):UrlWithStringQuery;function parse(urlStr:string,parseQueryString:true,slashesDenoteHost?:boolean):UrlWithParsedQuery;function parse(urlStr:string,parseQueryString:boolean,slashesDenoteHost?:boolean):Url;function format(URL:URL,options?:URLFormatOptions):string;function format(urlObject:UrlObject|string):string;function resolve(from:string,to:string):string;function domainToASCII(domain:string):string;function domainToUnicode(domain:string):string;function fileURLToPath(url:string|URL):string;function pathToFileURL(url:string):URL;interface URLFormatOptions{auth?:boolean;fragment?:boolean;search?:boolean;unicode?:boolean;}class URL{constructor(input:string,base?:string|URL);hash:string;host:string;hostname:string;href:string;readonly origin:string;password:string;pathname:string;port:string;protocol:string;search:string;readonly searchParams:URLSearchParams;username:string;toString():string;toJSON():string;}class URLSearchParams implements Iterable<[string,string]>{constructor(init?:URLSearchParams|string|NodeJS.Dict<string|ReadonlyArray<string>>|Iterable<[string,string]>|ReadonlyArray<[string,string]>);append(name:string,value:string):void;delete(name:string):void;entries():IterableIterator<[string,string]>;forEach(callback:(value:string,name:string,searchParams:this)=>void):void;get(name:string):string|null;getAll(name:string):string[];has(name:string):boolean;keys():IterableIterator<string>;set(name:string,value:string):void;sort():void;toString():string;values():IterableIterator<string>;[Symbol.iterator]():IterableIterator<[string,string]>;}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,29 @@
How to build the custom MONACO editor Node-RED
----------------------------------------------
### Building monaco
#### Setup build environment
cd /tmp/
git clone https://github.com/steve-mcl/monaco-editor-esm-i18n.git
#### Run the build
cd /tmp/monaco-editor-esm-i18n
npm install
npm build
#### Copy the built versions back
cd /tmp/monaco-editor-esm-i18n
cp -r output/monaco/dist \
<node-red-source-directory>/packages/node_modules/@node-red/editor-client/src/vendor/monaco/
cd /tmp/monaco-editor-esm-i18n
cp -r output/types \
<node-red-source-directory>/packages/node_modules/@node-red/editor-client/src/

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 - present Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,283 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize
This project incorporates components from the projects listed below. The original copyright notices and the licenses
under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted
herein, whether by implication, estoppel or otherwise.
%% nodejs path library (https://github.com/nodejs/node/tree/43dd49c9782848c25e5b03448c8a0f923f13c158)
=========================================
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF nodejs path library NOTICES AND INFORMATION
%% string_scorer version 0.1.20 (https://github.com/joshaven/string_score)
=========================================
This software is released under the MIT license:
Copyright (c) Joshaven Potter
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF string_scorer NOTICES AND INFORMATION
%% chjj-marked NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
=========================================
END OF chjj-marked NOTICES AND INFORMATION
%% typescript version 2.7.2 (https://github.com/Microsoft/TypeScript)
=========================================
Copyright (c) Microsoft Corporation. All rights reserved.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
=========================================
END OF typescript NOTICES AND INFORMATION
%% HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/)
=========================================
Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). This software or document includes material copied
from or derived from HTML 5.1 W3C Working Draft (http://www.w3.org/TR/2015/WD-html51-20151008/.)
THIS DOCUMENT IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF
THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY
PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE
DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF.
The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to this document or its contents
without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders.
=========================================
END OF HTML 5.1 W3C Working Draft NOTICES AND INFORMATION
%% JS Beautifier version 1.6.2 (https://github.com/beautify-web/js-beautify)
=========================================
The MIT License (MIT)
Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF js-beautify NOTICES AND INFORMATION
%% Ionic documentation version 1.2.4 (https://github.com/driftyco/ionic-site)
=========================================
Copyright Drifty Co. http://drifty.com/.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
=========================================
END OF Ionic documentation NOTICES AND INFORMATION
%% vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift)
=========================================
The MIT License (MIT)
Copyright (c) 2015 David Owens II
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF vscode-swift NOTICES AND INFORMATION

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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