Compare commits

..

808 Commits

Author SHA1 Message Date
Nick O'Leary
3d5ed840dc Bump version for 0.12.2 2015-11-28 20:32:19 +00:00
Nick O'Leary
11d75ff581 Inject time spinner incrementing value incorrectly 2015-11-26 09:56:49 +00:00
Nick O'Leary
306fb7a3d1 Kill processes run with exec node when flows redeployed 2015-11-24 23:09:44 +00:00
Nick O'Leary
0839b6f58e Debug node not handling null messages 2015-11-24 23:09:32 +00:00
Nick O'Leary
fceca703b3 Update tcp node status on reconnect after timeout
Closes #757
2015-11-24 22:40:39 +00:00
Nick O'Leary
4dc60d2477 Clarify debug rate limit method 2015-11-21 21:30:03 +00:00
Nick O'Leary
d840d0b67d Fix mqtt node lifecycle with partial deployments 2015-11-17 22:19:56 +00:00
Dave Conway-Jones
43dad4c465 ensure udp socket bind works more often 2015-11-16 08:38:22 +00:00
Dave Conway-Jones
60812b2d8a fix udp node messages
(timing issue still outstanding)
2015-11-16 00:25:26 +00:00
Nick O'Leary
35e2caff13 Handle errors thrown in Function node setTimeout/Interval 2015-11-15 22:22:17 +00:00
Nick O'Leary
1d9d5c6bc7 Add node 5 to travis 2015-11-14 21:32:28 +00:00
Nick O'Leary
4d99536ea7 Function setTimeout/Interval wrapper not returing timer id
Fixes #753
2015-11-14 21:21:14 +00:00
Nick O'Leary
34537180c3 Fix basic authentication on httpNode/Admin/Static 2015-11-10 15:44:48 +00:00
Nick O'Leary
cb01920ee6 Allow nodes to be installed by path name 2015-11-09 16:52:14 +00:00
Nick O'Leary
437b01a0ff Move node installer to its own module 2015-11-09 11:29:48 +00:00
Nick O'Leary
075a2abf71 Use child_process.execFile to prevent command injection 2015-11-08 14:26:11 +00:00
Nick O'Leary
985875cc75 Move node install/remove from server component to node engine 2015-11-08 14:06:36 +00:00
Nick O'Leary
1c45bc615f Enable touch-menu for links so they can be deleted 2015-11-06 16:46:07 +00:00
Nick O'Leary
fa7f2606fb bump version 2015-11-06 13:42:00 +00:00
Nick O'Leary
12b95f1c72 Enable config node dialog to have editor ui 2015-11-06 11:08:07 +00:00
Nick O'Leary
a0aee2021d Tidy up sheets/flows labelling 2015-11-05 14:22:15 +00:00
Nick O'Leary
c90fd1e6d8 Move credential http API handling to api component 2015-11-04 11:13:43 +00:00
Dave Conway-Jones
3b769fd2de add bash directive to nrgpio script 2015-11-04 08:42:00 +00:00
Nick O'Leary
71ecb89abc Merge branch 'flowengine' 2015-11-03 20:24:55 +00:00
Nick O'Leary
7b6bc1d3bc Increase default api request limit to 1mb
- expose it via settings.apiMaxLength
 - audit log api errors
2015-11-03 11:23:37 +00:00
Nick O'Leary
9c3be40fbe Automatically clear timeouts/intervals set in Function node
closes #744
2015-11-03 10:47:29 +00:00
Nick O'Leary
ab87fa9ce4 Ensure status/errors from global config nodes propagate properly 2015-11-03 10:20:00 +00:00
Nick O'Leary
d1940a023a Complete test coverage on flow engine refactor 2015-11-02 15:58:40 +00:00
Nick O'Leary
5a176a037c Update test helper for refactored flow engine 2015-11-02 15:58:40 +00:00
Nick O'Leary
ec25191c98 Flow Engine refactor
Each flow/tab now exists as its own logical object. This is the ground
work for allowing flows to be added/removed/updated independently.
2015-11-02 15:58:29 +00:00
Nick O'Leary
20b321f928 Handle null subflow info property 2015-10-26 11:12:49 +00:00
Dave Conway-Jones
425b016d63 Add missing space to label in delay node 2015-10-26 09:42:16 +00:00
Nick O'Leary
b2c7189ce4 Update package dependencies 2015-10-25 21:36:20 +00:00
Nick O'Leary
f66886dbdb Websocket input node not unsubscribing properly
Fixes #739
2015-10-23 23:01:25 +01:00
Nick O'Leary
712f8b4680 Add description field to Subflows 2015-10-23 22:14:39 +01:00
Nick O'Leary
f626ee060a Allow properties to be specified by environment variables
A property set to $(ABC) will be substituted with the environment
variable ABC - if it exists. If the property doesn't exist, the property
is left unchanged.
2015-10-23 22:14:39 +01:00
Dave Conway-Jones
86aa7c97be Make exec node status indication consistent with others 2015-10-22 19:02:22 +01:00
Dave Conway-Jones
30e3525987 Add status icon to trigger node while it is active 2015-10-22 16:27:07 +01:00
Dave Conway-Jones
ad44f838da update sample to refer to fa-icons 2015-10-20 19:30:42 +01:00
Dave Conway-Jones
2569a35b6c fix closing web socket timeout
to close #738 - thanks to @GSeva for spotting it.
2015-10-20 18:58:37 +01:00
Dave Conway-Jones
1ee5e50d50 Turn on tcp node socket keepalive when in server mode 2015-10-20 10:13:48 +01:00
Dave Conway-Jones
1dbec5eca8 slight tidy of Pi Mouse node 2015-10-20 10:02:57 +01:00
Nick O'Leary
2bc8db308c Add missing tab-config file 2015-10-17 19:05:23 +01:00
Nick O'Leary
f196740426 Restore config node tab 2015-10-16 21:56:20 +01:00
Dave Conway-Jones
20121b79c5 Let CSV node handle null columns in input array. array-> csv 2015-10-16 20:42:25 +01:00
Nick O'Leary
741a4cfe53 Don't assume def.align is set to 'right'
Fixes #734
2015-10-15 14:27:30 +01:00
Dave Conway-Jones
0343de9f34 Add status capability to function node 2015-10-15 13:33:05 +01:00
Nick O'Leary
4772bca14a Undo 'selection to subflow' not restoring nodes 2015-10-15 11:34:17 +01:00
Dave Conway-Jones
6ae1a5ba0d let CSV obj->css allow blank columns in template 2015-10-15 08:31:42 +01:00
Dave Conway-Jones
217c9718e4 catch missing template error in CSV parser node
and update help info
2015-10-14 23:38:29 +01:00
Dave Conway-Jones
61d7893467 Enhance CSV node to accept simple arrays -> css 2015-10-14 23:07:25 +01:00
Dave Conway-Jones
8f26c01f4b fix escaping of quotes in CSV node 2015-10-14 11:02:31 +01:00
Dave Conway-Jones
61045ddd7f try to fix debug node non-standard object type handling. 2015-10-10 22:41:07 +01:00
Dave Conway-Jones
1bf72a0bc3 correct TCP node server status message 2015-10-09 15:44:22 +01:00
Dave Conway-Jones
6d84b1bb8d update inspect to come from correct package (util)
(works from v0.10 onwards - but now deprecated in v4)
2015-10-09 13:36:35 +01:00
Dave Conway-Jones
8abd0b1fdf Detect/set correct method for http proxy
to close #732 — thanks @utaani
2015-10-09 09:19:09 +01:00
Dave Conway-Jones
81e125b7ba add bit more help to exec node
Point out that parameters with spaces should be quoted
2015-10-05 21:41:53 +01:00
Dave Conway-Jones
d5e1468718 Normalise spawn behaviour in exec node to accept identical parameters
Can now just tick or untick spawn and command still works.
2015-10-05 21:17:35 +01:00
Nick O'Leary
c232bf5ed6 Avoid unnecessary isUtf8 check on HTTP payloads 2015-10-05 21:10:32 +01:00
Nick O'Leary
21b25ffaee Merge pull request #730 from jthomas/master
Allow HTTP nodes to handle non-UTF8 content.
2015-10-05 20:52:35 +01:00
Dave Conway-Jones
ca0a93df08 Add Node-RED sag icon to default images 2015-10-05 13:46:42 +01:00
James Thomas
699a22c757 Allow HTTP nodes to handle non-UTF8 content.
Setting UTF-8 as the default body encoding stops us sending binary
content, e.g. audio, which can be decoded into a Buffer.

Use "Content-Type" header to decide whether to decode as UTF-8 or a
Buffer.
2015-10-05 11:53:29 +01:00
Nick O'Leary
8b2b1669b5 Add ignore-case flag to Switch regex rule
closes #366
2015-10-04 22:14:49 +01:00
Dave Conway-Jones
c1e8370916 Lets spawn msg.payload contain comma separated parameters
(like rest of parameters passed in to spawn via edit dialogue)
Will also accept an array…
2015-10-04 19:22:33 +01:00
Nick O'Leary
ddedea8b90 Resize change/switch rules with the dialog 2015-10-03 22:30:28 +01:00
Nick O'Leary
8f414ce458 Update auth revoke test for express 4 2015-10-03 20:32:24 +01:00
Nick O'Leary
453f23da20 Move to node 4.x.x in travis 2015-10-03 09:15:11 +01:00
Nick O'Leary
9e91e42a1b Increase delay burst test timeout
The test was occasionally timing out, despite it succeeding. Increased
the timeout to give it a bit more safety margin to complete
2015-10-03 09:06:51 +01:00
Nick O'Leary
b666734c79 Update dependency versions 2015-10-02 22:13:15 +01:00
Nick O'Leary
a2297f303d Update config node user list when node edits are undone 2015-10-02 21:27:31 +01:00
Nick O'Leary
ecde942255 Wrap msg.req/res objects and add deprecated warnings to functions 2015-10-02 21:27:31 +01:00
Nick O'Leary
d668d43a0a Move to express 4.x 2015-10-02 21:27:31 +01:00
Nick O'Leary
ca91a5dd95 Rename flow menu ids back to workspace 2015-10-02 21:27:31 +01:00
Nick O'Leary
5f9780d71c Improve error message if settings file fails to load 2015-10-02 21:27:31 +01:00
Nick O'Leary
ee37464741 Copy settings file to userDir on start-up if it makes sense
It will only copy the file if:
 - a custom file hasn't been specified (-s file)
 - there isn't an existing settings.js file in userDir
 - the default settings file (in install dir) hasn't been
   modified (mtime < ctime)
2015-10-02 21:27:31 +01:00
Nick O'Leary
8d73f927db Debug output should use overridden toString method if set
Closes #690
2015-10-02 21:27:31 +01:00
Nick O'Leary
4a0222bd1c Warn if a node references an unknown config node type
Closes #709
2015-10-02 21:27:31 +01:00
Nick O'Leary
c0b8f5e3e1 Add tab info to deploy error messages 2015-10-02 21:27:31 +01:00
Nick O'Leary
a9a0b263dc Add undo support for config-node delete 2015-10-02 21:27:30 +01:00
Nick O'Leary
f2b73187d8 Name flows back to sheets in the ui 2015-10-02 21:27:30 +01:00
Nick O'Leary
ef10ade0cc Improve handling of imported config nodes
Avoid creating unnecessary duplicates of config nodes, whilst
honouring the scope of the any existing node.

Also, 'undo' now removes any added config node
2015-10-02 21:27:30 +01:00
Nick O'Leary
719bb4263e Ensure config nodes are deleted when owning subflow is deleted 2015-10-02 21:27:30 +01:00
Nick O'Leary
b3602b268e Have grunt dev restart on message catalog changes 2015-10-02 21:27:30 +01:00
Nick O'Leary
66ec9bae27 Add warning if HTTP In node is missing path config 2015-10-02 21:27:30 +01:00
Nick O'Leary
d96b6e77c0 Allow config nodes to be scoped to an individual Flow 2015-10-02 21:27:30 +01:00
Nick O'Leary
da64c018ac Make the comms link be more tolerant to temporarily blips 2015-10-02 21:27:30 +01:00
Nick O'Leary
f9fb97adf2 Undo subflow rename not updating corresponding tab/menu labels 2015-10-02 21:27:30 +01:00
Nick O'Leary
8316bc6480 Move config node users tip into body of dialog 2015-10-02 21:27:30 +01:00
Nick O'Leary
08021e039a Better favicon 2015-10-02 21:27:30 +01:00
Dave Conway-Jones
cc6e0937a0 initialise status.text to be blank string if not set.
(and change test to use .text rather than .message)
(not that it matters at this level of test)
2015-10-02 21:27:30 +01:00
Nick O'Leary
c1d694a97c Add birth message to MQTT node 2015-10-02 21:27:30 +01:00
Dave Conway-Jones
fcf4f40c36 add basic status node test 2015-10-02 21:27:30 +01:00
Nick O'Leary
380b03399c Update to latest MQTT module version 2015-10-02 21:27:29 +01:00
Nick O'Leary
c33d02c53f Ensure MQTT node cleansession/keepalive defaults are used 2015-10-02 21:27:29 +01:00
Nick O'Leary
fa5e37993e Update mqtt node options to include will/cleansession/keepalive 2015-10-02 21:27:29 +01:00
Richard Ruston
437b2d506b Update MQTT node to use MQTT.js 1.2 and enable secure connections 2015-10-02 21:27:29 +01:00
Dave Conway-Jones
4ed09f6431 update FA icons to v4.4.0 2015-10-02 21:27:29 +01:00
Nick O'Leary
0b98a6acf8 Ensure catch/status nodes marked changed when edited 2015-10-02 21:27:29 +01:00
Nick O'Leary
1d73c86cb2 Add scope to status node 2015-10-02 21:27:29 +01:00
Nick O'Leary
40fe0f3239 Test Node.status calls through to Flow.handleStatus 2015-10-02 21:27:29 +01:00
Nick O'Leary
d1ea689999 Update catch node help text 2015-10-02 21:27:29 +01:00
Nick O'Leary
a6644ad5ff Add status node 2015-10-02 21:27:29 +01:00
Nick O'Leary
658746d2a3 Allow flow file to be specified with grunt dev
For example: grunt dev --flowFile=flows.json
2015-10-02 21:27:29 +01:00
Nick O'Leary
cbdd4de630 Errors in subflows propagate up to nearest catch node 2015-10-02 21:27:29 +01:00
Nick O'Leary
00c612485b Fix jshint errors 2015-10-02 21:27:29 +01:00
Nick O'Leary
3a6192bf73 Catch node can target specific nodes 2015-10-02 21:27:28 +01:00
Nick O'Leary
c64b5c2850 Add subflow tab image 2015-10-02 21:27:28 +01:00
Nick O'Leary
fdbf079896 Clean up subflow editor
- new appearance of subflow tabs
 - input/output buttons now counters
 - allow multiple input wires to the same node when converting to subflow
 - ensure edit history is propagated properly to instance nodes
2015-10-02 21:27:28 +01:00
Dave Conway-Jones
d1a5395727 update test for JSON parser to include array 2015-10-02 19:46:29 +01:00
Dave Conway-Jones
83a3642c0e Allow JSON node to handle array type 2015-10-02 17:30:23 +01:00
Nick O'Leary
9932d34304 Fix XML parse test
Workaround to https://github.com/Leonidas-from-XIV/node-xml2js/issues/239
2015-09-29 14:39:07 +01:00
Nick O'Leary
7aa37a1976 Bump version 2015-09-29 10:17:45 +01:00
Dave Conway-Jones
fa42fbdab8 Let XML node options be set
let msg.options to set a lot more options if required
2015-09-26 13:47:14 +01:00
Nick O'Leary
caa83ac830 Merge pull request #724 from vielmetti/travis-node-4
Support for Node 4.0.0 and Travis CI testing for same
2015-09-25 23:02:49 +01:00
Nick O'Leary
3963fa9738 Allow a language catalog to be a partial catalog 2015-09-24 21:56:45 +01:00
Edward Vielmetti
005a98d020 Update for node 4 testing.
Changes to .travis.yml
Patch from @dceejay to make a test portable
Patch from @dceejay to correct a case where an int was expected
2015-09-23 15:27:45 -04:00
Dave Conway-Jones
9560dc9408 remove delay spinner upper limit
e.g. 65 secs is perfectly valid…
close #728
2015-09-22 15:06:58 +01:00
Nick O'Leary
4ac9a5edf0 Merge pull request #726 from vielmetti/patch-2
Bump uglify to 2.4.24 to address security advisory
2015-09-22 10:15:54 +01:00
Edward Vielmetti
37e62597ae Bump uglify to 2.4.24 to address security advisory
Noted in https://nodesecurity.io/advisories/uglifyjs_incorrectly_handles_non-boolean_comparisons
2015-09-20 01:21:21 -04:00
Dave Conway-Jones
90bfe378d0 Add mobile category to palette order 2015-09-16 22:35:17 +01:00
Dave Conway-Jones
ce22b494ec Update README to use svg badges
to close #720
Thanks to @scherwi for the tip
2015-09-08 21:47:57 +01:00
Nick O'Leary
f9e0420647 Fix http node method-override nls message id 2015-08-31 16:06:00 +01:00
Dave Conway-Jones
2fe568d9ba Fix TCP node sending data
(it’s for the children)
2015-08-17 17:15:44 +01:00
Dave Conway-Jones
2d4979df4d only set tcp timeout if needs setting. 2015-08-15 22:16:48 +01:00
Dave Conway-Jones
b555b014b8 Update debug test to check lengths... 2015-08-12 21:56:19 +01:00
Dave Conway-Jones
999b888c54 debug nodes - show length of strings, buffers or size of arrays 2015-08-11 19:39:37 +01:00
Nick O'Leary
5193d7bddb Stop sending messages to ws connections that have errored
Fixes #708
2015-07-30 22:09:01 +01:00
Nick O'Leary
6b03379e4e Ensure exclusive conf node is removed on edit cancel
- If an exclusive conf node was added to a node, but the
   node's own edit dialog was canceled, the conf node remained
   but not associated with the node - effectively orphaning it
2015-07-22 22:28:30 +01:00
Nick O'Leary
08d687ad60 Update to travis container builds 2015-07-22 13:06:14 +01:00
Nick O'Leary
eb57089f06 Add flag to disable build check for tests 2015-07-22 11:41:58 +01:00
Nick O'Leary
a76e4fede1 Handle null acceptedLanguages
Closes #704
2015-07-19 22:11:25 +01:00
Nick O'Leary
705d043540 Replace bootstrap popover 2015-07-18 21:27:16 +01:00
Nick O'Leary
5462e251f8 Fix exclusive config node check when type not registered 2015-07-15 13:23:05 +01:00
Nick O'Leary
50788af6ca Add 0.12 to engine statement 2015-07-15 10:50:38 +01:00
Nick O'Leary
1a07c5a329 Bump 0.11.0 2015-07-15 10:48:33 +01:00
Nick O'Leary
9fb81b2814 Permit login with blank scope
Required for the editor, which doesn't know the appropriate scope
for the user logging in. The user will adopt their default permission
scope once logged in.
2015-07-15 10:12:45 +01:00
Dave Conway-Jones
10ad7fbf6e remove spaces before ? in messages 2015-07-14 23:47:58 +01:00
Nick O'Leary
811c4f2630 Ensure locales dir is included in release zip 2015-07-14 20:37:49 +01:00
Dave Conway-Jones
f7e3b0a64f Tiny pixel tweaks to new ui 2015-07-14 20:37:26 +01:00
Nick O'Leary
7d83d76fb3 Merge pull request #702 from node-red/ui-refresh
UI Refresh
2015-07-14 16:11:48 +01:00
Nick O'Leary
d3c41b38f7 More restylin 2015-07-14 15:59:56 +01:00
Nick O'Leary
57d6b16d5c Reset sidebar font size 2015-07-13 23:30:57 +01:00
Nick O'Leary
27aa5ae7db More UI refresh 2015-07-13 23:21:03 +01:00
Nick O'Leary
62e8f564b9 Fix node import error nls message 2015-07-13 16:28:23 +01:00
Nick O'Leary
a1d7bb4208 More restyling - workspace buttons 2015-07-13 15:08:17 +01:00
Nick O'Leary
5d8dae05c4 More ui redesign 2015-07-13 11:26:29 +01:00
Nick O'Leary
6bde07b5a0 Refresh appearance 2015-07-11 23:43:45 +01:00
Nick O'Leary
846ab08661 Allow node modules to declare supported versions of node-red 2015-07-10 21:42:14 +01:00
Nick O'Leary
999cf66b27 Add editor events component and migrate to it 2015-07-10 19:49:53 +01:00
Dave Conway-Jones
60539d890b Fix File node check of msg.payload to close #700
Also add feature to allow creation of directory(ies) if path to file
does not exist.
2015-07-10 14:59:23 +01:00
Nick O'Leary
e5a0f25d94 Keep sidebar tab menu in alphabetical order 2015-07-09 16:48:53 +01:00
Nick O'Leary
fde9d40098 Copy/clone config nodes properly on import/export 2015-07-08 22:12:52 +01:00
Nick O'Leary
f70e9ea076 Ensure RED._ is defined before initialising settings
- remove permissions requirement from locales files so the
   login dialog can be nls'd
2015-07-08 17:08:07 +01:00
Dave Conway-Jones
d0af4aac4d cleanup status on delay node 2015-07-08 15:06:46 +01:00
Dave Conway-Jones
7de3704210 lets exec node pass more than just string as the command payload. 2015-07-08 15:06:08 +01:00
Nick O'Leary
1c33b837b8 Fix delay node labels 2015-07-08 08:04:47 +01:00
Nick O'Leary
95d20d7fba Ensure status messages are strings 2015-07-08 08:02:23 +01:00
Nick O'Leary
90b8806e7c Merge pull request #697 from knolleary/node12
Add node 0.12 to Travis config and fix resulting errors
2015-07-05 23:11:19 +01:00
Nick O'Leary
39df80bf99 Fix exec test to restart helper server before each test 2015-07-05 23:02:10 +01:00
Nick O'Leary
bac4beae03 Fix Function error parsing for node 0.12 format 2015-07-05 22:40:24 +01:00
Nick O'Leary
a7b68c18b5 Bump fs-extra version to fix 0.12 support 2015-07-05 22:10:34 +01:00
Nick O'Leary
ef2360baee Add node 0.12 to Travis config 2015-07-04 22:08:58 +01:00
Nick O'Leary
8716e7e601 Ensure tab minimum size not applied when there is space for all 2015-07-03 20:54:31 +01:00
Nick O'Leary
00c2dae969 Set minimum size on workspace tab 2015-07-03 18:31:37 +01:00
Nick O'Leary
8782bc5896 Ensure sidebar panes are hidden, not removed on change 2015-07-03 11:17:27 +01:00
Nick O'Leary
6359b90352 Add sidebar menu and migrate existing panels to new api 2015-07-03 10:07:40 +01:00
Nick O'Leary
6cfa4976fe Fix nodes.install.installing message id 2015-07-02 13:25:15 +01:00
Nick O'Leary
35cd7cf2b8 Fix tcp status message 2015-07-02 10:56:27 +01:00
Nick O'Leary
b2d7f079b7 Merge pull request #694 from node-red/i18n
Add i18n support
2015-07-02 10:54:22 +01:00
Nick O'Leary
726069bc4b NLS status text in editor not runtime 2015-07-02 10:49:40 +01:00
Nick O'Leary
fbccf01933 Tidy up red.js runtime messages 2015-07-02 10:49:40 +01:00
Nick O'Leary
c9f3c6f4a3 Update trigger node ui 2015-07-02 10:49:40 +01:00
Nick O'Leary
c47da013ff Tidy up of editor i18n messages 2015-07-02 10:49:40 +01:00
Allen Boone
bc76499957 Use core category for custom nodes if core nodes disabled 2015-07-02 10:49:40 +01:00
Allen Boone
24afcff0ea Custom nodes category NLS 2015-07-02 10:49:40 +01:00
Nick O'Leary
6777f24845 Ensure library export dialog is i18n'd 2015-07-02 10:49:40 +01:00
Nick O'Leary
61e0923fc4 Restore when module dependency in red/api/nodes 2015-07-02 10:49:40 +01:00
Nick O'Leary
757caeb9a4 Try to use default palette label nls message if found 2015-07-02 10:49:40 +01:00
Allen Boone
fe9dc6b272 Palette category label NLS for core nodes 2015-07-02 10:49:40 +01:00
Nick O'Leary
24efdbe4da Add missing-type install hint nls messages 2015-07-02 10:49:39 +01:00
Nick O'Leary
9ca102cf81 Ensure error messages are toStringed 2015-07-02 10:49:39 +01:00
Nick O'Leary
48df31d7b7 NLS deprecated node message 2015-07-02 10:49:39 +01:00
Nick O'Leary
539afb1e1d Fix Inject node interval label 2015-07-02 10:49:39 +01:00
Nick O'Leary
bdcba44ca5 Remove moved node messages 2015-07-02 10:49:39 +01:00
Nick O'Leary
99a51b07ac Catch error loop detection nls 2015-07-02 10:49:39 +01:00
Allen Boone
5fbaca75b4 Fixed sidebar id issue 2015-07-02 10:49:39 +01:00
Allen Boone
a6974371b0 Fixed acceptedLanguage typo 2015-07-02 10:49:39 +01:00
Allen Boone
409fa49234 Added missing NLS strings to sidebar and index.mst 2015-07-02 10:49:39 +01:00
Nick O'Leary
9bbd6a70b8 Add namespaced i18n function to node definition 2015-07-02 10:49:39 +01:00
Nick O'Leary
f0b4cb608a Return locale specific node help 2015-07-02 10:49:39 +01:00
Allen Boone
284d7e26d1 Initialize list of supported languages from directories in the locale folder. 2015-07-02 10:49:39 +01:00
Scott Yoshizawa
965c0937ac NLS undo previous change (added require for ./red/log) 2015-07-02 10:49:39 +01:00
Nick O'Leary
d9cf6a4431 Only attempt to load one locale per catalog 2015-07-02 10:49:39 +01:00
Allen Boone
e6ed8ee509 locale exposed to editor 2015-07-02 10:49:39 +01:00
Scott Yoshizawa
2563649b3e NLS /red/nodes
NLS other js files under /red

NLS /red files (changed based on Nick's review)
2015-07-02 10:49:39 +01:00
Nick O'Leary
203bc41b06 Some more node i18n tidy up 2015-07-02 10:49:38 +01:00
Allen Boone
cb1d18c7c8 Fixed problem with RED._ being unavailable to module code 2015-07-02 10:49:38 +01:00
Nick O'Leary
5ea68dafc4 More node i18n tidy ups 2015-07-02 10:49:38 +01:00
Nick O'Leary
68bb8252af Ensure i18n func available to new config nodes 2015-07-02 10:49:38 +01:00
Nick O'Leary
406f742d29 Add jsonlint step to build 2015-07-02 10:49:38 +01:00
Nick O'Leary
5522e57f65 More node i18n tidy-up 2015-07-02 10:49:38 +01:00
Nick O'Leary
94e27dbfc5 Tidy up node i18n 2015-07-02 10:49:38 +01:00
Nick O'Leary
f5fc8f763f Pick up desired language from query string 2015-07-02 10:49:38 +01:00
Nick O'Leary
9058bf615c Fix invalid json in message catalog 2015-07-02 10:49:38 +01:00
Nick O'Leary
9d17137dec Ensure i18n message for Unknown nodes are available 2015-07-02 10:49:38 +01:00
Allen Boone
4a318553f7 Updated editor ui NLS strings 2015-07-02 10:49:38 +01:00
Allen Boone
0017074d38 Updated the notifications and errors to use NLS
removed errant comma
2015-07-02 10:49:36 +01:00
Allen Boone
a39a26fcc2 Converted editor menu to use NLS strings 2015-07-02 10:47:02 +01:00
Scott Yoshizawa
2fe859b111 NLS Core nodes
NLS exec node

NLS function/temple/delay nodes

NLS function/template/delay/trigger/comment nodes

NLS io nodes (mqtt/httpin/websocket/watch/serial)

NLS messages.json for tcpin

NLS io nodes (tcpin & udp half)

NLS io nodes (udp)

NLS logic nodes (switch/change)

NLS logic (range) and parsers (csv&html) nodes

NLS parser nodes (json/xml)

NLS test case update for logic/parsers

NLS analysis and hardware nodes

NLS storage nodes (file/redisout/mongodb) and test

NLS storage node (tail)

NLS social nodes (feedparse/email/irc)

NLS socal node (twitter half change)

NLS social node (twitter) and core node (unknown)
2015-07-02 10:46:57 +01:00
Nick O'Leary
c105b2df37 Add RED._ to test helper 2015-06-29 16:04:00 +01:00
Nick O'Leary
4fb86ab55a Fix !=0 comparison 2015-06-29 16:04:00 +01:00
Nick O'Leary
1ed98a5963 Dont create i18n function for subflows 2015-06-29 16:04:00 +01:00
Nick O'Leary
a4a29ceb3c Handle [html] data-i18n prefixes in config node dialog 2015-06-29 16:04:00 +01:00
Nick O'Leary
6249083431 Extract all core runtime messages 2015-06-29 16:04:00 +01:00
Nick O'Leary
aa18c65fa8 NLS enable the Inject node 2015-06-29 16:03:59 +01:00
Nick O'Leary
a7900940da Expose i18n in editor 2015-06-29 16:03:59 +01:00
Nick O'Leary
008bc98070 Ensure node help is blank if otherwise undefined 2015-06-29 16:03:59 +01:00
Nick O'Leary
0705589cc2 Load base locales in editor 2015-06-29 16:03:59 +01:00
Nick O'Leary
b2caba593f Add locales api endpoint 2015-06-29 16:03:59 +01:00
Nick O'Leary
6d4c64fcd5 i18n enable runtime node files 2015-06-29 16:03:59 +01:00
Nick O'Leary
7d41781fb4 Add initial red/i18n implementation 2015-06-29 16:03:59 +01:00
Nick O'Leary
0760facb77 Add .DS_store to gitignore 2015-06-29 16:02:01 +01:00
Nick O'Leary
a0ce095807 Error generating complete flow library list on OSX
Must use path.join to concatenate paths safely.
2015-06-29 16:00:10 +01:00
Nick O'Leary
df0110913a Remove rogue console.logs 2015-06-25 15:33:39 -07:00
Nick O'Leary
06731374a4 Fix trigger extend behaviour 2015-06-25 13:59:26 -07:00
Dave Conway-Jones
6c8b7c0082 Correct RPi pins labels... and add BCM pins also. 2015-06-24 12:39:27 +01:00
Dave Conway-Jones
93136961b9 make unspecified settings file totally obvious in debug. 2015-06-22 14:17:16 +01:00
Dave Conway-Jones
529a691e1d Add clearTimeout to function node sandbox
(to be a pair with setTimeout…)
2015-06-22 09:07:31 +01:00
Dave Conway-Jones
9f0b3eba47 Add basic exec node test 2015-06-22 08:26:38 +01:00
Nick O'Leary
6d897793cb Ensure node.outputs is always a number
Closes #686
2015-06-19 20:37:12 +01:00
Nick O'Leary
0e12fc6b02 Fix canvas focus issue on FF/IE 2015-06-17 22:52:04 +01:00
Nick O'Leary
c00558ea1b Remove old index.html 2015-06-17 22:46:54 +01:00
Dave Conway-Jones
bacf27a3ca mistook 2015-06-17 22:12:48 +01:00
Dave Conway-Jones
6560ea0630 Delete Dockerfile
mistook
2015-06-17 22:12:27 +01:00
Nick O'Leary
8338231ce5 Drop blank port from comms ws path 2015-06-17 22:09:27 +01:00
Dave Conway-Jones
5813a91244 adjust timing on file tail test
Runs cleaner on Mac
2015-06-17 22:08:53 +01:00
Nick O'Leary
dfd8ab3545 Detect mouse paste in Import nodes dialog 2015-06-17 20:48:56 +01:00
Nick O'Leary
a5b9b949a8 bump to 0.10.11 dev version 2015-06-17 14:58:22 +01:00
Nick O'Leary
72570e4510 Fix scope of knownUnknowns variable 2015-06-17 14:27:49 +01:00
Nick O'Leary
3002aead6b Add better install message on missing nodes 2015-06-17 14:18:47 +01:00
Nick O'Leary
841edbe6fb Ensure release files retain proper chmod status 2015-06-17 13:38:49 +01:00
Nick O'Leary
2b9aca0c56 Add bin to release package 2015-06-16 23:39:33 +01:00
Nick O'Leary
3a17c3ee6d Merge pull request #680 from cpswan/patch-1
https link (rather than git) in dev instructions
2015-06-16 23:38:58 +01:00
Chris Swan
df09252ee0 https link (rather than git) in dev instructions 2015-06-16 23:20:10 +01:00
Nick O'Leary
f51778d417 Bump to 0.10.9 2015-06-16 22:19:31 +01:00
Nick O'Leary
119fc63794 Bump version and dependencies 2015-06-16 21:27:44 +01:00
Nick O'Leary
ee3425d3be Normalise ace editor font size 2015-06-16 20:56:09 +01:00
Nick O'Leary
31c979f30f Add deprecated node list 2015-06-16 15:32:41 +01:00
dceejay
89f2c26cd6 Give our own linked core nodes some leeway on version number
so we can apply fixes without bumping package - which was the whole point of moving them out...
2015-06-16 08:40:39 +01:00
dceejay
0dbf43d0aa Update Gruntfile so only core nodes are linted. 2015-06-15 20:38:40 +01:00
dceejay
8a6d11b191 tiny lint thing in debug node... missing ; 2015-06-15 20:38:09 +01:00
dceejay
d8eb926e2c Move out several core node to node-red-nodes ready for 0.10.8
Update package.json to match.
Part of #668
2015-06-15 20:37:36 +01:00
Nick O'Leary
21d0adbdae Handle null message in catch loop detection 2015-06-15 15:22:51 +01:00
Nick O'Leary
c5fd3a5753 Detect and prevent Catch node loops 2015-06-15 15:09:50 +01:00
Nick O'Leary
eae4e3d983 Add deploy warning for unused config nodes 2015-06-10 14:52:58 +01:00
Nick O'Leary
bb1fe8daef Allow nodesExcludes to specify node module name 2015-06-08 23:17:45 +01:00
Nick O'Leary
c5d8e09b41 Only delete node type from registry if id matches
If a node is moved out of node-red core to an npm installable
package, the first time NR runs after the move it correctly
deletes the node-red version from the registry. However it was
also removing the node constructors registered by the new
npm installed version as it wasn't checking what it was removing
came from the now-removed node.
2015-06-08 16:32:50 +01:00
dceejay
369eae3d92 remove http response function call example from info. (being deprecated) 2015-06-03 22:53:27 +01:00
Nick O'Leary
e2fa457ca2 Minimise amount of node redrawing done during drag 2015-06-03 10:05:31 +01:00
Nick O'Leary
871f764e98 Allow node icon definition to be a function 2015-06-02 22:07:45 +01:00
Nick O'Leary
f8853af902 Enabling metric/audit logging takes precedence over level 2015-06-02 16:23:38 +01:00
Nick O'Leary
4248d20f39 Add RED.util.generateId and ensure HTTP node adds proper id 2015-06-02 15:54:37 +01:00
Nick O'Leary
5cda08e7b0 Update trigger node UI 2015-05-31 20:58:28 +01:00
dceejay
7e9d96ee87 Let email node set a default filename for binary attachment
so it will send "something" if only a buffer arrives.
2015-05-31 20:27:27 +01:00
dceejay
974ac31d33 Hide right sidebar on start if screen narrower than 600px
so at last you can see something that looks like Node-RED
2015-05-31 12:58:42 +01:00
Nick O'Leary
0658b70631 Inject node not parsing 0-23 hour range correctly 2015-05-29 22:28:42 +01:00
Nick O'Leary
53258eeede Restore ability to add nodes by filename 2015-05-27 14:11:11 +01:00
dceejay
4f174308b9 Fix tcp node miscounting bytes, and check if staying connected first. 2015-05-26 20:08:58 +01:00
dceejay
98c9e40349 Add small note re escaping test to inject node. 2015-05-26 20:04:12 +01:00
dceejay
3a4756bd83 let urllib parse proxy url more cleanly in http-request node. 2015-05-23 18:55:11 +01:00
dceejay
6ccb05cb2c http-request node - relax proxy regex check to let userid:password through 2015-05-21 17:45:11 +01:00
dceejay
3c2d32b867 Correct incorrect pwm "tip" info for RPI GPIO node
Closes #648
Thanks @edent
2015-05-21 17:03:59 +01:00
dceejay
956050434f Add no_proxy to http-request node.
also make it support HTTP_PROXY and NO_PROXY (ie uppercase)
2015-05-19 11:07:54 +01:00
dceejay
38ab1550d2 change http request to use http_proxy environment rather than do it ourselves 2015-05-19 10:00:06 +01:00
dceejay
e852d1e57c remove unrequired require from Arduino node 2015-05-19 10:00:06 +01:00
Nick O'Leary
7de0216976 Add audit log entries on API calls
Closes #627
2015-05-14 14:22:56 +01:00
dceejay
911288e695 Arduino node - improved logging and port error handling. 2015-05-13 22:26:01 +01:00
dceejay
72e1f20383 Arduino - ensure port list populated on start,
also allow connect to first found board - by not specifying a port.
2015-05-13 21:59:15 +01:00
Nick O'Leary
d28a6eaf9d Add httpNodeMiddleware option
Closes #631

Enables custom middleware to be inserted in front of all HTTP In
nodes.
2015-05-13 21:25:37 +01:00
dceejay
17f3366556 Adds proxy support to http node - via settings.js 2015-05-13 13:54:47 +01:00
Nick O'Leary
0bef04ae0a Set NODE_ENV in grunt dev task to serve non-minified assets 2015-05-11 20:24:15 +01:00
dceejay
f11b906fd9 Websocket - fix broken test (or rather - fix code to pass test) 2015-05-10 10:00:44 +01:00
dceejay
518358d9dc Websocket - add reconnect capability when running as a client.
to close #643

Also adds node.status to nodes.
2015-05-10 00:12:52 +01:00
dceejay
5ffde21d83 revert change to editor change detector, and redo function node valid
code "flag" to report as non-boolean.
2015-05-08 15:31:48 +01:00
dceejay
052302b3e7 actually set valid to be false in function so .toString will work... 2015-05-07 22:02:46 +01:00
Nick O'Leary
fe1ce21114 toString values before checking for changes 2015-05-07 21:17:06 +01:00
Nick O'Leary
ce5c9da107 Ensure ace edit history is reset after initialisation 2015-05-07 21:12:46 +01:00
dceejay
cf25b2866e Allow http to accept delete properly, and put, options etc. 2015-05-07 16:45:44 +01:00
dceejay
07fd5a5f5f function node was marking changed even on no change. 2015-05-07 16:44:55 +01:00
Nick O'Leary
913fdac671 Add support for exclusive config nodes 2015-05-06 11:08:01 +01:00
Nick O'Leary
7dc838dea6 Fix click on debug message to reveal source node 2015-05-05 22:00:47 +01:00
Nick O'Leary
7112fd2a22 Partial deploy containing deleted subflow throws error 2015-05-05 13:53:40 +01:00
dceejay
56e8c143dd CONTRIBUTING - remove link to specific Issues (so we can use this file
for all the projects)
2015-05-05 12:50:46 +01:00
dceejay
7b4cbbe816 Add try catch to exec node stdout if utf8 check fails 2015-05-05 12:50:46 +01:00
Nick O'Leary
8f8ee4662d Initialise checkboxes in config editor for new nodes 2015-05-05 00:03:35 +01:00
Nick O'Leary
86013c7db4 Ensure node.credentials exists for nodes with registered creds
Fixes #639
2015-05-04 23:28:55 +01:00
Nick O'Leary
01aa3324f8 Fix lint error in user.js 2015-05-03 22:28:03 +01:00
Nick O'Leary
b9cfeee965 Navigate and submit login dialog with Enter key 2015-05-03 22:23:30 +01:00
Nick O'Leary
b3684a70b5 Handle Buffer payloads in HTTP Response node 2015-05-02 22:20:46 +01:00
Nick O'Leary
51fce9343b Ensure errors in node.receive are handled 2015-05-02 22:15:33 +01:00
Nick O'Leary
0c5c3448d0 Merge pull request #633 from scott1y/Issue#626
Added the capability to register custom loggers (for Issue #626)
2015-05-02 21:53:07 +01:00
Scott Yoshizawa
deaef3ab86 Corrected based on knolleary's comments. 2015-05-01 09:37:23 -04:00
Nick O'Leary
a443491c0c Merge pull request #630 from lostinthestory/swagger-gen
Added support for swagger doc to HTTP-In
2015-05-01 09:32:57 +01:00
Scott Yoshizawa
276d893198 Added the capability to register custom loggers (for Issue #626) 2015-04-30 17:01:22 -04:00
Nick O'Leary
653d0e71e4 Add meta tag for IE edge compatibility 2015-04-28 14:25:41 +01:00
Nick O'Leary
faa7d948a7 Update MQTT Out node status if already connected 2015-04-27 20:08:00 +01:00
Nick O'Leary
771342989e HTTP Request - handle null url
Fixes #632
2015-04-26 08:50:42 +01:00
Cody Walker
e9ce519e4b Added support for swagger doc to HTTP-In 2015-04-24 13:53:38 -05:00
Nick O'Leary
c016b102eb Add async error handler to UDP out node
Fixes #629
2015-04-24 11:17:18 +01:00
Nick O'Leary
0583c60837 Editor link filter failing for src_port == 0
Fixes #621
2015-04-22 22:53:21 +01:00
Nick O'Leary
1c1a85dcef editorTheme: allow header logo/title to be a link 2015-04-22 14:03:42 +01:00
Nick O'Leary
c71e76335b Serial Out not appending character
Fixes #622
2015-04-21 09:43:00 +01:00
Nick O'Leary
c1a32c4eb9 Merge pull request #620 from drwoods/master
fix 3 localfilesystem tests failing on Windows
2015-04-20 15:27:38 +01:00
drwoods
9ad1f769d3 localfilesystem tests failing on Windows 2015-04-20 10:13:00 -04:00
Nick O'Leary
87f8fd34b8 Ensure full deploy is visually selected by default 2015-04-20 11:17:27 +01:00
dceejay
e206d2919e More defensive on closing tcp connections,
and tidy up some lint
2015-04-19 12:13:45 +01:00
dceejay
9d809aa2ba Point Grunt to use external jshintrc 2015-04-16 11:53:39 +01:00
dceejay
8f744794e4 push opinionated .jshintrc - matches Grunt build. for starters. 2015-04-16 10:22:12 +01:00
Nick O'Leary
78ab4217be Arduino pin values should be strings not numbers 2015-04-15 09:34:03 +01:00
Nick O'Leary
d090df94c5 Arduino output - ensure string/number payloads handled
A change to tighten the type checking meant passing a string
'0' or '1' no longer matched the tests for numeric 0 or 1.
2015-04-14 23:14:13 +01:00
Nick O'Leary
937f26da41 Merge pull request #606 from drwoods/master
Ignore Eclipse project files and fix some jshint warnings
2015-04-14 21:34:23 +01:00
drwoods
98e3ff014e ignore Eclipse files and resolve some Eclipse JSHint warnings
squashed 4 commits into 1
2015-04-14 14:17:08 -04:00
dceejay
6f84526364 Remove pre-req for mkdirp package.
(fs-extra has all the features needed already)
2015-04-14 18:41:48 +01:00
dceejay
105d38c885 MQTT node - don't report missing topic if payload is missing... 2015-04-14 18:39:42 +01:00
dceejay
d7bdcd69fc fix exec missing addpayload,
improve switch null test (to include null object)
check mqtt has payload before sending
2015-04-14 17:15:56 +01:00
Nick O'Leary
87e537da90 Merge pull request #611 from node-red/themes
Editor Themes
2015-04-13 22:51:52 +01:00
Nick O'Leary
8f16695f06 Add theme tests 2015-04-13 22:15:15 +01:00
Nick O'Leary
8403f6291f Tidy deploy button css 2015-04-13 21:50:40 +01:00
Nick O'Leary
5af6ac3e80 Rename menu ids to be logically consistent 2015-04-13 16:48:38 +01:00
Nick O'Leary
0d557094b2 Move help customisation under menu settings 2015-04-13 15:32:11 +01:00
Nick O'Leary
a2aa78afd4 Add main menu customisation 2015-04-13 13:55:17 +01:00
Nick O'Leary
b0de8abb63 Customise help link label/url 2015-04-13 11:35:52 +01:00
Nick O'Leary
6ff540ed08 Customise login image 2015-04-13 10:37:30 +01:00
Nick O'Leary
2b8ed9850b Pass deployButton and userMenu theme options to ui 2015-04-13 09:48:49 +01:00
Nick O'Leary
dcd579b5e3 Some scss tidy up 2015-04-13 00:11:32 +01:00
Nick O'Leary
c9d2d301aa Add editorTheme setting 2015-04-13 00:11:11 +01:00
Nick O'Leary
1aaef598a5 Concatenate vendor js/css where possible 2015-04-13 00:10:10 +01:00
dceejay
73d1f3d0e8 Expose rest of email node header fields. 2015-04-12 00:46:03 +01:00
Nick O'Leary
e369ded6c5 Allow deploy button to be customised 2015-04-11 22:51:00 +01:00
dceejay
269846c587 Catch bad folder error in email node 2015-04-11 19:24:32 +01:00
dceejay
8dc98420db handle pure plain text messages in email node. 2015-04-11 16:48:50 +01:00
dceejay
1014abe92f Fix email node repeat send, add to, cc, bcc fields, and ability to select inbox. 2015-04-11 16:09:13 +01:00
Nick O'Leary
6927f10f8f Fix login image path 2015-04-10 15:39:29 +01:00
Nick O'Leary
49d3a7190a Update nodemonignore/watch rules 2015-04-09 22:18:37 +01:00
Nick O'Leary
a2e65b0018 Prepend copyright to built editor files 2015-04-09 21:12:39 +01:00
Nick O'Leary
f48ee01a03 Ensure MQTT nodes unsubscribe before disconnect
Fixes #609

Needed for partial deployment - the nodes assumed the
connection would always be closed when a deploy occurs.
2015-04-09 20:10:34 +01:00
Nick O'Leary
0e926c566b Add missing header scss 2015-04-09 17:26:11 +01:00
Nick O'Leary
d2c4c2c34c Split css into individual scss files 2015-04-09 14:46:29 +01:00
Nick O'Leary
c2253d1e25 Merge pull request #608 from node-red/build2
Add build process to grunt
2015-04-09 13:02:01 +01:00
Nick O'Leary
eae16b6e8c Add tests for build check 2015-04-09 12:13:46 +01:00
Nick O'Leary
868ae5b5dd Add .dist to gitignore 2015-04-09 11:37:16 +01:00
Nick O'Leary
1406503e10 Add build info to README 2015-04-09 10:22:05 +01:00
Nick O'Leary
9ca9d88546 Drop Node 0.8 from travis build due to devDependencie issues 2015-04-09 10:22:05 +01:00
Nick O'Leary
203d3f672c Add build step to Grunt file 2015-04-09 10:22:05 +01:00
dceejay
698b2688f6 Add port, ssl and allow self signed certs to IRC node 2015-04-09 09:55:34 +01:00
dceejay
be1620dd07 Fix watch node to stat file sizes ok
(and also not to when file missing)
2015-04-08 21:43:44 +01:00
Nick O'Leary
e1f0969957 Add dedicated route for editor index.html 2015-04-08 21:29:55 +01:00
Nick O'Leary
e1dd8cf2ab Restore node order in palette following async changes
The move to async loading of node files led to them appearing
out of order in the palette.
2015-04-08 20:17:24 +01:00
dceejay
8ee90777ee Move serialport (and irc) to optional dependancies so installs ok in more places.
(albeit without serialport etc... - but not many clouds have serialports)
2015-04-08 09:55:48 +01:00
Nick O'Leary
2fe9c1e55f Change node config load to be async 2015-04-07 23:46:52 +01:00
Nick O'Leary
9dd7e2e43d Refactor registry structure
Splits registry up into smaller components.

Unit tests still drive api via registry/index_spec - still
need to split them up into the currently blank _spec files
2015-04-07 16:02:15 +01:00
Nick O'Leary
5efbdf5d04 Revert removal of flow storage api
Whilst we know with the file system storage inplementation
getLibraryEntry is a suitable replacement for getFlow, this
may not be the case with other implementations.

The storage code uses the deprecated functions if they are
present - so the core code should call them and let the storage
layer decide what it calls.
2015-04-05 20:54:11 +01:00
dceejay
5be3472413 For some reason http request node icon was aligned right,
inconsistent with most other "function" nodes...
2015-04-05 17:57:06 +01:00
dceejay
a9a0953653 Slide timing window to left for trigger node test. 2015-04-04 22:27:25 +01:00
Nick O'Leary
d4ac4c44d0 Fix library test for deprecated storage api 2015-04-04 19:33:37 +01:00
Nick O'Leary
f459ff8ad0 Remove use of deprecated storage api 2015-04-04 19:25:07 +01:00
Nick O'Leary
b96ea36b70 Deprecate getAllFlows/getFlow/saveFlow storage functions
They were specialised versions of get/saveLibraryEntry that
complicated the interface.

This change removes them from localfilesystem, but the top
level module checks for their existence and uses them if
they are there - for backwards compatibility.
2015-04-03 23:05:56 +01:00
Nick O'Leary
e543cc0fed Log settings file in use on start up 2015-04-03 23:05:15 +01:00
Nick O'Leary
0b1b4df210 Update README / Remove INSTALL.md 2015-04-02 21:19:57 +01:00
Nick O'Leary
e59ffb0b19 Bump to dev version 0.10.7 2015-04-01 10:48:57 +01:00
Nick O'Leary
120c8f2c28 Bump version 0.10.6 2015-04-01 10:28:04 +01:00
Nick O'Leary
fbfc5c8a2d Add error codes to api responses 2015-03-31 22:29:42 +01:00
dceejay
31b018c80e Missed closing brace in email node fix 2015-03-31 16:39:00 +01:00
dceejay
255d708fb6 updates to serial, watch, websocket, udp, twitter, email to handle no payload. 2015-03-31 09:21:11 +01:00
dceejay
78d1da5fbc Updates to sentiment, exec and range to handle missing payload properties 2015-03-31 08:35:56 +01:00
dceejay
9c22a770ef remove superfluous console.log from debug node 2015-03-30 21:59:54 +01:00
Nick O'Leary
b201828236 Remove 'loaded' property from external node info object
and fix everything that doing this broke
2015-03-30 21:49:20 +01:00
Nick O'Leary
2a8a885271 Standardise API error response format 2015-03-30 14:16:04 +01:00
Nick O'Leary
7adefd6ee0 Add access_token expiry 2015-03-30 14:14:32 +01:00
Nick O'Leary
f967a5ecdc Fix auth on comms link and for anon user
The move to honour scope level of token broke the comms link
checking as well as the permissions checking for anon users.
2015-03-29 22:27:07 +01:00
Nick O'Leary
c8d6dc2531 Auth permission should honour the token scope 2015-03-29 21:59:48 +01:00
Nick O'Leary
216b5fba7a Increment subflow name on import of duplicate 2015-03-28 22:12:18 +00:00
Nick O'Leary
f4ec9a72d5 Increase tab max-width 2015-03-28 22:08:39 +00:00
Nick O'Leary
cf0c2825eb Expand palette category when first entry added 2015-03-28 21:46:27 +00:00
Nick O'Leary
be46c419dc Center palette label whilst being dragged 2015-03-26 20:08:25 +00:00
Nick O'Leary
62c68d06fe Merge pull request #598 from dceejay/dcjtests
new tests for sentiment, file and csv nodes
2015-03-26 16:57:04 +00:00
Nick O'Leary
4f4d8419bc Nudge palette labels to rebalance them 2015-03-26 16:55:55 +00:00
dceejay
16e17954b4 add try catch to helper shutdown,
tiny fixes for exec and trigger based on tests
2015-03-26 15:02:08 +00:00
Nick O'Leary
cc1d080a5a Remove add/removeNode by filename api
Only support add/remove by module name
2015-03-26 11:39:35 +00:00
Nick O'Leary
dd7f4f6752 Filter loaded property from /nodes endpoint 2015-03-26 11:38:51 +00:00
Nick O'Leary
9daeba02b5 Flow.registerType should indicate if type was missing or not 2015-03-26 11:37:24 +00:00
dceejay
8a96dbd121 New tests for Trigger, catch and unknown nodes 2015-03-25 21:58:26 +00:00
Nick O'Leary
2a57d0b6d0 auth/login should return empty object when insecure 2015-03-25 20:33:29 +00:00
dceejay
8a5c1bade5 new tests for sentiment, file and csv
(inc a bugfix for csv :-)

tweka of 0.8 ?

temp remove buffer should equall test from file node test

comment out failing test in file node (0.8 specific fail...)

stagger multiple writes slightly in file test
2015-03-25 14:58:57 +00:00
dceejay
fcc6943f98 Extra tests for html, xml, json and tail nodes
(and some consistent passing of missing payloads)
2015-03-24 17:43:47 +00:00
dceejay
72a9de058d tests for defaults in switch, change and range nodes. 2015-03-24 17:35:54 +00:00
Nick O'Leary
8748be28b7 Bump to 0.10.5 2015-03-23 10:56:14 +00:00
Nick O'Leary
20bdea7ae0 Increase registry test coverage 2015-03-22 22:54:52 +00:00
Nick O'Leary
e19b8d35a9 Modules not properly removed from config.json 2015-03-22 21:48:12 +00:00
Nick O'Leary
81df74dfc8 Server not waiting for settings to load 2015-03-22 20:55:38 +00:00
Nick O'Leary
153fa7478f Increase flows test coverage 2015-03-22 20:12:10 +00:00
Nick O'Leary
500e9a4010 Increase localfilesystem test coverage 2015-03-22 17:40:42 +00:00
dceejay
5352fc87ee add extra tests to debug, delay & template 2015-03-22 09:38:42 +00:00
dceejay
f07fd64ffb Make trigger have sensible defaults when dragged on. 2015-03-21 19:27:39 +00:00
Nick O'Leary
36f299c031 Improve core test coverage 2015-03-21 17:42:06 +00:00
Nick O'Leary
78cf310c58 Collapse palette category when emptied 2015-03-20 23:12:52 +00:00
Nick O'Leary
18a3d71024 Double-click on subflow palette node to open flow 2015-03-20 23:11:24 +00:00
Nick O'Leary
26db1048f9 Remove dialog close button via css not jquery 2015-03-20 23:11:03 +00:00
Nick O'Leary
b61a250d58 Debug message formatting mangling brackets 2015-03-20 22:09:58 +00:00
Nick O'Leary
1d10eba0cc Propagate changed flag to parent subflow 2015-03-20 21:20:04 +00:00
Nick O'Leary
35042132fa Make node-info properties collapsable in sidebar 2015-03-20 21:13:00 +00:00
Nick O'Leary
57c049b49f Palette filter on label as well as id 2015-03-20 11:40:34 +00:00
Nick O'Leary
7a0ce0c957 Update style of nodes in palette to match workspace 2015-03-20 11:37:47 +00:00
Nick O'Leary
eb4cadb0b5 Propagate valid flag to parent subflows 2015-03-19 23:11:55 +00:00
Nick O'Leary
ac0ca083c0 Import of subflow loses certain internal wires
Wires between subflow inputs and outputs are getting lost when
JSON is imported.
2015-03-19 22:59:09 +00:00
dceejay
9afb4a9315 reverse overide behaviour on file, http and email. Node properties now
have priority. Warn user if msg.property tries to override. 
Warning should  be removed at next major verion bump.
2015-03-19 21:25:43 +00:00
dceejay
df065e94b7 add extra tests to user_spec to test some else conditions. 2015-03-19 19:57:41 +00:00
dceejay
a9789697e7 add bcrypt as optional dependency to speed up Pi,
but not force compile on Windows.
Fix to close Issue #585
2015-03-19 11:36:48 +00:00
Nick O'Leary
2d91be8814 Disable node buttons in subflow view
Closes #592
2015-03-19 11:19:44 +00:00
Nick O'Leary
5c58b0c2f4 Revalidate all config node users after edit 2015-03-19 10:49:56 +00:00
Nick O'Leary
f0139f9808 Add multi-rule support to Change node 2015-03-18 16:20:50 +00:00
dceejay
5610a3184e small spelling mistake in deploy.js 2015-03-17 15:38:31 +00:00
Nick O'Leary
b202c73708 Allow access_token to be provided in url 2015-03-17 15:15:24 +00:00
Nick O'Leary
dd4cec84bf Add node.send/on to Function node 2015-03-17 13:40:12 +00:00
Nick O'Leary
a1dac1e290 Resize ace editor on dialog-open 2015-03-17 13:36:50 +00:00
Nick O'Leary
e199d6725e Test helper - initialise credentials with express instance 2015-03-16 21:57:31 +00:00
dceejay
aef38b945d Change http request node info to suggest {{{ rather than {{ to supress
html escape when forming urls from mustache.
2015-03-16 20:22:25 +00:00
dceejay
cd5eac2cbb Add type and size reporting to the file watch node. 2015-03-16 20:21:05 +00:00
dceejay
8fea443e71 Add error msg to rpi node 2015-03-16 17:09:13 +00:00
dceejay
2a47951e46 make sure MQTT msg has a topic 2015-03-16 17:07:46 +00:00
dceejay
5234fda266 Tidy up arduino node slightly and update settings example to work nicer
with JohnnyFive
2015-03-16 17:07:17 +00:00
Nick O'Leary
e63067cd9f Add OS X command symbol to keyboard dialog 2015-03-16 15:40:25 +00:00
Nick O'Leary
be61cf6a88 Add node.error handling to core nodes 2015-03-16 13:58:01 +00:00
Nick O'Leary
5efc89d514 Warn when leaving editor with undeployed changes 2015-03-15 23:48:02 +00:00
Nick O'Leary
9c104faff3 Use RED.nodes.filterLinks in pref to RED.nodes.eachLink 2015-03-15 23:41:16 +00:00
Nick O'Leary
cf8fe16b09 Remove direct access to RED.nodes.nodes/links
- Adds RED.nodes.filterNodes and RED.nodes.filterLinks for
   doing simply queries to find elements that match a criteria
2015-03-15 23:31:38 +00:00
Nick O'Leary
71db193675 Move user menu creation to user module 2015-03-15 23:07:57 +00:00
Nick O'Leary
9952d9451e Move deploy menu/action to own module 2015-03-15 22:54:55 +00:00
Nick O'Leary
fb738ad9fa Track dirty state in RED.nodes not RED.view
- add 'change' event on RED.nodes for tracking dirty state change
2015-03-15 21:54:36 +00:00
Nick O'Leary
46f2f752b0 Node on deleted tab not removed on partial deploy 2015-03-15 21:27:11 +00:00
Nick O'Leary
42730b8fce Move external drag/drop to clipboard module 2015-03-14 22:53:31 +00:00
Nick O'Leary
1c2be579d9 Move keyboard shortcut dialog to keyboard module 2015-03-14 22:16:07 +00:00
Nick O'Leary
51e891ff88 Move sessionStorageModule into main storageModule
Fixes #586

 - add get/saveSessions to main storage module
 - handle storage modules without those functions
 - store .session file in userDir
2015-03-13 23:37:59 +00:00
Nick O'Leary
731efe1c01 Add credential extract unit tests 2015-03-13 21:26:50 +00:00
Nick O'Leary
f77dd06e65 Partial deploy with missing type breaks flow diff
Another refactor of Flow lifecycle.
 - diffFlow made a private static function
 - applyConfig now diffConfig - which returns a diff object that
   can be passed to .stop/.start to be properly applied
2015-03-13 17:54:58 +00:00
Nick O'Leary
af20f3df64 Partial deploy with missing node type breaks deploy 2015-03-13 13:15:20 +00:00
Nick O'Leary
4078212089 Split cliboard and workspaces out of editor view 2015-03-12 23:38:37 +00:00
Nick O'Leary
7bdb3181e2 Don't reload page on enter in subflow dialog 2015-03-12 17:23:17 +00:00
Nick O'Leary
933608aec1 Disable buttons of nodes with undeployed changes 2015-03-12 13:58:53 +00:00
Nick O'Leary
1d7f06bbba Redraw unselected link when joining nodes starts 2015-03-12 13:35:39 +00:00
Nick O'Leary
f26cadab7f Minimise link redrawing 2015-03-12 13:26:31 +00:00
Nick O'Leary
eacf41a4f6 Minimise filtering of nodes on redraw 2015-03-12 11:21:05 +00:00
Nick O'Leary
ab3e64271b Move subflow handling to own module 2015-03-12 00:09:30 +00:00
Nick O'Leary
e26ea14104 Undo subflow rename not reflected in palette 2015-03-12 00:09:30 +00:00
dceejay
3967e23828 change settings to replace commented out arduino library
with johnny-five to match example in docs to make life easier.
2015-03-11 17:49:06 +00:00
dceejay
1f8c6f87c9 add don't add payload to exec node
to close #578
2015-03-11 17:43:42 +00:00
Nick O'Leary
f6203fe60a Allow a config-node be marked as not required 2015-03-09 20:42:23 +00:00
Nick O'Leary
06bf710515 Improve editor dialog auto-sizing 2015-03-09 20:41:57 +00:00
Nick O'Leary
0f3cc3196c Log-in window incorrect
fixes #583
2015-03-09 20:02:13 +00:00
dceejay
4403a00651 Revert change to http until we fully deprecate msg/node priorities
Fix to close #582
2015-03-08 18:36:35 +00:00
dceejay
9c46feb22b more tests for log and Node 2015-03-08 16:53:48 +00:00
dceejay
10277aa956 revert/redo tests for api/index, log and Node_spec 2015-03-08 15:26:47 +00:00
Nick O'Leary
ff093d98c6 Merge pull request #576 from Belphemur/function-logger
Adding an Object Node to the sandbox of a function node
2015-03-07 23:37:00 +00:00
dceejay
acc0e0875b few more tests for permissions and strategies
reset log flags at end of log test
2015-03-07 13:22:21 +00:00
dceejay
69f85bd688 boost api index, nodes index and nodes Node test coverage 2015-03-06 22:58:30 +00:00
dceejay
910d983b82 More tests for red, log, info and util. 2015-03-06 14:14:47 +00:00
dceejay
128415bc9e back out some changes to red_spec test while investigate fail on v0.8 2015-03-06 10:51:57 +00:00
dceejay
082ce798d8 slightly enhance test coverage for info and log and settings. 2015-03-06 10:18:33 +00:00
dceejay
234abd82a2 Move away from __defineGetter syntax, in red and server
Bump test coverage forwards a bit
2015-03-06 10:17:00 +00:00
dceejay
3cbc1bbb1b Add ipv6 support to udp node 2015-03-05 13:07:38 +00:00
Antoine Aflalo
0ed9f6cc4f Adding an Object node to the sandbox of a function node
Permit the user of the sandbox to log using the Function Node.
Test provided and working.

Fix Display warning message in the debug log
Before they were displayed as error instead of warning
2015-03-05 09:50:11 +02:00
Nick O'Leary
10b092a9a7 Ignore 'type' when detecting config nodes 2015-03-04 22:38:53 +00:00
Nick O'Leary
444a897410 Resort to NODE_RED_HOME if User HOME not found
Fixes #575
2015-03-04 21:47:38 +00:00
Nick O'Leary
e013afb053 Import/Export dialogs cannot be cancelled
Fixes #577
2015-03-04 21:44:14 +00:00
Nick O'Leary
34364f5627 Allow node to register multiple close handlers
Closes #573
2015-03-04 21:42:11 +00:00
Nick O'Leary
cef378d820 Add selection-changed event on RED.view 2015-03-04 13:22:32 +00:00
Nick O'Leary
a27353c166 Add onadd/onremove event handlers to node definitions 2015-03-04 13:22:29 +00:00
dceejay
bbd197c71d Note in info that MQTT node can support binary. 2015-03-03 15:56:42 +00:00
Nick O'Leary
fabf013714 Allow the main view hold keyboard focus 2015-03-02 22:55:34 +00:00
dceejay
81dcfecb4e Catch very early exit null pointer when ctrl-c hit during startup. 2015-03-02 17:32:22 +00:00
Nick O'Leary
971a62ebc9 Merge pull request #571 from knolleary/errnode
Add Catch node
2015-02-26 22:58:03 +00:00
Nick O'Leary
04f2c92ba6 Add subflow/catch node tests 2015-02-26 22:40:54 +00:00
Nick O'Leary
00d0f8cfc7 Invoke catch node only when msg is provided 2015-02-26 22:40:54 +00:00
Nick O'Leary
c5c404ea05 Update catch node icon and help text 2015-02-26 22:40:54 +00:00
Nick O'Leary
c80a44933c Add errorHandler tests 2015-02-26 22:40:54 +00:00
Nick O'Leary
5599b999ec Add catch node 2015-02-26 22:40:53 +00:00
Nick O'Leary
172cbdaa84 Merge pull request #574 from knolleary/editor
Migrate to ACE editor
2015-02-26 22:27:02 +00:00
Nick O'Leary
a3c4f12764 Bump 0.10.4 2015-02-26 21:39:30 +00:00
Nick O'Leary
bf1cd457cd Add RED.editor.createEditor utility function 2015-02-26 21:29:56 +00:00
dceejay
8af50a51ba add validation triangle to ace function editor on errors 2015-02-26 17:08:50 +00:00
Nick O'Leary
ddf31e87b2 Update core nodes to use ACE editor 2015-02-26 17:08:50 +00:00
Nick O'Leary
5adbc012f3 Add ACE editor 2015-02-26 17:08:50 +00:00
Nick O'Leary
393fc349b9 Fix saving for node-library content 2015-02-26 17:08:20 +00:00
dceejay
dfed4963ed fix big labelling issue with Pi + pins ... 2015-02-26 14:18:49 +00:00
dceejay
131adb6f4e let email node mark mail as read
(for the ones it reads)
2015-02-26 14:18:49 +00:00
dceejay
a8b3cbb683 remove unecessary require from serial node 2015-02-26 14:18:49 +00:00
Nick O'Leary
e97d5c7354 Rename node-red wrapper to node-red-pi 2015-02-26 13:41:01 +00:00
Nick O'Leary
061c44f958 Move shebang to the correct red.js 2015-02-26 13:24:38 +00:00
Nick O'Leary
f5d8433341 Add node-red-pi command 2015-02-26 11:38:05 +00:00
Nick O'Leary
f78a71e8ed Load flows file from userDir when appropriate 2015-02-26 11:30:20 +00:00
Nick O'Leary
4d48c72146 Add node-red script
Needed to allow arguments to be passed to the node
engine, which isn't possible if red.js is run with
a #! line.
2015-02-25 22:37:56 +00:00
dceejay
71ff828947 Tidy up all console.log util.log from core nodes.
Try to make log,warn,error more consistent behaviour.

Especially make sure any existing catches produce errors
2015-02-25 19:10:59 +00:00
Nick O'Leary
b6245bdef7 Remove console.log from XML test spec 2015-02-25 14:25:37 +00:00
Nick O'Leary
ce1cd1ab9c Change default data dir
Changes the default location for user data to $HOME/.node-red.
2015-02-25 14:25:01 +00:00
dceejay
54b0debb3b Re-order palette categories, move subflows to top of list. 2015-02-25 10:10:10 +00:00
Nick O'Leary
1876b56022 Fix jshint error 2015-02-24 23:06:07 +00:00
Nick O'Leary
d148a23ed6 Handle config nodes appearing out of order in flow
The editor ensures config nodes appear first in the flow file. The
code in the runtime and editor assumes this to be the case, so that
when a node is instantiated that requires a config node, it can assume
the config node already exists.

This change allows a config node to appear in the flow file after a
node that wants to use it. In both the editor and runtime, the code
now scans for config nodes and handles them first.
2015-02-24 23:04:55 +00:00
dceejay
049a5f1be6 revert small whitespace change to server start messages. 2015-02-24 22:22:16 +00:00
Nick O'Leary
f3880b7601 Fix credential pruning and start/stop log messages 2015-02-24 22:03:04 +00:00
dceejay
fbb45a8961 make udp node consistent with it's info.... (re params passed out) 2015-02-24 13:22:48 +00:00
dceejay
b8c460b825 pass original url request through http request node
(will be useful when we handle errors... ;-)
2015-02-24 13:20:33 +00:00
Nick O'Leary
63191bc641 Bump 0.10.3 2015-02-23 22:18:14 +00:00
dceejay
9f012c261a Make parser nodes errors actual errors.
(more cleanup will probably be necessary - but this is a start)
2015-02-23 19:30:29 +00:00
dceejay
dc7701ad70 Add node.js version to startup log msgs for debug. 2015-02-23 19:30:29 +00:00
Nick O'Leary
e8666827e6 Restore httpAdminAuth with deprecation warning 2015-02-23 11:39:38 +00:00
Nick O'Leary
5e2c51a741 Handle deleted tab when diffing flows 2015-02-22 22:59:26 +00:00
dceejay
51421ce657 clone msg more correctly for CSV node multiple line output 2015-02-22 21:57:06 +00:00
Nick O'Leary
339e6039e1 Add engine restriction against node 0.12 2015-02-22 21:28:28 +00:00
dceejay
43054906dc preserve other msg properties when passing through CSV node 2015-02-22 19:23:36 +00:00
Nick O'Leary
57dedcf816 Add files to .gitignore 2015-02-21 00:28:29 +00:00
Nick O'Leary
4dc21c43fa Handle strings for limit/skip args to mongo node 2015-02-20 20:02:25 +00:00
Nick O'Leary
1c86908b90 Bump 0.10.2 2015-02-20 10:07:10 +00:00
Nick O'Leary
9b26973883 Ensure activeWorkspace is set when a flow contains no tabs 2015-02-20 10:05:42 +00:00
Nick O'Leary
2585e983a5 Add test-* grunt tasks 2015-02-15 23:35:24 +00:00
Nick O'Leary
a808cb44c2 Merge pull request #563 from emiloberg/master
Fixes bug that prevented unsubscribe from WebSockets, browser side. Fixes node-red/node-red/#562
2015-02-15 21:54:48 +00:00
Nick O'Leary
edd9d2cb9c Fix Inject node handling of day selection
Fixes #564
2015-02-15 21:53:14 +00:00
Emil Öberg
33d24f79ce Fixes bug that prevented unsubscribe from WebSockets, browser side. Fixes node-red/node-red/#562 2015-02-14 22:25:25 +01:00
dceejay
cc095e4edf edit HTML node info to remove ref to jQuery. Link to CSSselect instead. 2015-02-14 19:06:35 +00:00
dceejay
07641d57ab recorrect debug logging level colour class names so sidebar is as-was.
in light of new logging levels
2015-02-14 12:14:06 +00:00
dceejay
5643c51507 Let debug node show "topic" correctly for errors in functions. 2015-02-13 21:14:54 +00:00
Nick O'Leary
ad6254c0b8 Add oneditdelete handler for config nodes
Already had the undocumented ondelete handler. Adding
this to be consistent with the other oneditXYZ handlers.
2015-02-13 11:20:08 +00:00
Nick O'Leary
d6ca421d59 Remove unecessary argument to oneditcancel 2015-02-13 11:05:45 +00:00
Nick O'Leary
79bd01f810 Remove X button on dialogs
Fixes #561

Also, oneditcancel not being honoured for regular nodes, only config nodes
2015-02-13 10:06:28 +00:00
Nick O'Leary
e357352240 Tidy up info tab handling of subflows and comments 2015-02-10 21:29:27 +00:00
dceejay
0accfade02 catch internal subflow info error in tab-info... 2015-02-10 20:15:00 +00:00
dceejay
00b7afe3ae spelling pedant alert in debug node... its not it's 2015-02-10 20:14:33 +00:00
dceejay
2e76541fa5 Update Debug node test to "unbreak" build... oops 2015-02-10 17:31:26 +00:00
dceejay
e2911078e3 tidy up tab-info so subflows show more useful information
(was broken before but no-one noticed ;-)
(and reorder fields in HTTP and XML nodes so name comes out first - ocd)
2015-02-10 16:56:07 +00:00
dceejay
c6157687c9 Move payload type label in Debug window to meta data row
rather than (object) etc at start of actual payload.
2015-02-10 16:56:07 +00:00
Nick O'Leary
87a1818486 Add missing FA font file 2015-02-09 09:48:31 +00:00
Nick O'Leary
d6c5d91e2c Remove package.json from gitignore because it breaks everything 2015-02-08 23:14:37 +00:00
Nick O'Leary
e042d9e8cd Bump version 0.10.0 2015-02-08 23:03:48 +00:00
dceejay
07c8c4bb45 Let Pi GPIO node show pins in use to help avoid clashes. 2015-02-08 19:40:23 +00:00
dceejay
2dd572f5bd Allow msg.description to add to the email body text
(for feed from Fluickr node)
2015-02-08 15:02:02 +00:00
dceejay
d4a27f88a1 Allow Email node to send html, and add attachments.
(outbound only at present)
2015-02-08 11:33:04 +00:00
dceejay
1513dbfcdd Add strict flag to debug (for consistency with others) 2015-02-08 11:32:26 +00:00
Nick O'Leary
8451c29a25 Add line/col report test 2015-02-07 19:56:22 +00:00
Nick O'Leary
ae7f1b38a8 Add line/col reporting to Function runtime errors 2015-02-07 19:52:14 +00:00
Nick O'Leary
83dad88ad3 Fix debug reporting of warning/errors 2015-02-07 19:29:43 +00:00
Nick O'Leary
8eb1a02407 Fix unit test failures following mocha upgrade 2015-02-06 17:27:43 +00:00
Nick O'Leary
1e6f45852f Update package dependencies 2015-02-06 17:17:44 +00:00
Nick O'Leary
3849855b57 Rename _id to _msgid to avoid mongo clash 2015-02-06 16:36:32 +00:00
Nick O'Leary
f2712f296b Update to font-awesome 4.3 2015-02-06 13:57:33 +00:00
Nick O'Leary
c7f13e3d0c Add needsPermission protection to core nodes 2015-02-06 13:57:15 +00:00
Nick O'Leary
d1fe997bf7 Doc updates 2015-02-06 13:16:46 +00:00
Nick O'Leary
86c8a5de81 Allow palette categories to be predefined 2015-02-06 13:16:19 +00:00
Nick O'Leary
010abbd3d5 Remove deprecated nodes 2015-02-06 11:33:04 +00:00
Nick O'Leary
3123aa6279 Merge pull request #558 from knolleary/auth
Add bearer token authentication to Editor
2015-02-06 11:28:12 +00:00
Nick O'Leary
dedda19626 Restyle user menu 2015-02-06 11:27:21 +00:00
Nick O'Leary
c31ffb98b0 Tie auth middleware to needsPermission api 2015-02-05 23:43:35 +00:00
Nick O'Leary
3ef6f29d6e Add Log.trace/debug/error functions 2015-02-05 17:05:39 +00:00
Nick O'Leary
26c42e500f Allow user.default to be an api function 2015-02-05 13:01:00 +00:00
Nick O'Leary
53a515176b Remove unused token expiry code 2015-02-05 13:01:00 +00:00
Nick O'Leary
fbf7ee50eb Increase unit test coverage of auth code 2015-02-05 13:00:56 +00:00
Nick O'Leary
b2aae93fa6 Hide user profile menu 2015-02-05 13:00:55 +00:00
Nick O'Leary
a494954275 Add permissions and user menu 2015-02-05 13:00:55 +00:00
Nick O'Leary
f5d7903ecb Stop lost connection message bouncing when not authed 2015-02-05 13:00:55 +00:00
Nick O'Leary
9bbe0799bd Allow adminAuth setting to provide functions 2015-02-05 13:00:55 +00:00
Nick O'Leary
f3eb85c449 Move over to settings.adminAuth 2015-02-05 13:00:54 +00:00
Nick O'Leary
74e1ef0823 Add auth awareness to comms channel 2015-02-05 13:00:49 +00:00
Nick O'Leary
982997c3df Add auth awareness to ui 2015-02-05 13:00:49 +00:00
Nick O'Leary
66005a2688 Use jquery ajax rather than d3 2015-02-05 13:00:49 +00:00
Nick O'Leary
42cd6f94a7 fix settings 2015-02-05 13:00:37 +00:00
Nick O'Leary
dfc20f3cc9 Add node-red logo for login screen 2015-02-05 13:00:29 +00:00
Nick O'Leary
2b5a1ce6d4 Add settings changes 2015-02-05 13:00:16 +00:00
Nick O'Leary
28823802ea Prompt login if auth enabled 2015-02-05 13:00:16 +00:00
Nick O'Leary
2128b57ab2 Add oauth grant 2015-02-05 13:00:07 +00:00
Nick O'Leary
c8ccacb035 Switch node sortable entries diable inputs in FF 2015-02-05 10:46:01 +00:00
dceejay
3334c795e0 Correct spelling in Pi error messages, fix mouse icon file type 2015-02-04 23:27:51 +00:00
Nick O'Leary
b97d251787 Add on-headers dependency to package.json 2015-02-04 22:32:27 +00:00
Nick O'Leary
482c4e9c5e Add memory metric reporting 2015-02-04 22:28:17 +00:00
Nick O'Leary
1712146836 Clear loghandlers on init and supress output in tests 2015-02-04 21:29:11 +00:00
Nick O'Leary
c8d2d690f0 Rename HTTP In content-length metric 2015-02-04 21:10:18 +00:00
Nick O'Leary
f2d4648384 Support of HTTP Node metrics 2015-02-04 20:48:46 +00:00
dceejay
86ca75bcd5 Pi Node status not displaying 0 fixed. 2015-02-04 19:02:32 +00:00
Nick O'Leary
31aa3901cc Fix global leak in localfilesystem 2015-02-04 15:41:18 +00:00
Nick O'Leary
ab831c34f3 Enable node status by default 2015-02-04 15:23:28 +00:00
Nick O'Leary
8443e48240 Place flows backup alongside flow file
Also backup credentials file in the same manner.
2015-02-04 15:23:28 +00:00
dceejay
a08b29dbd1 Add info to Twitter out node to make it obvious how to do DMs. 2015-02-04 11:36:43 +00:00
Nick O'Leary
97621b41b9 Ensure deleted core nodes are removed from config list 2015-02-04 10:27:02 +00:00
Nick O'Leary
f462446213 Make Function duration status optional 2015-02-04 10:01:46 +00:00
hbeeken
6b96c1876a changing function node metrics to new infrastructure 2015-02-04 09:46:54 +00:00
Nick O'Leary
0aaea1ec40 Update logging/metric system 2015-02-03 22:02:26 +00:00
hbeeken
7d6ce1ec12 Changing metric logging to take a primative rather than an object 2015-02-03 19:12:09 +00:00
hbeeken
b052324d36 Adding logging & metric recording configuration via settings 2015-02-03 19:12:09 +00:00
dceejay
a22f819f40 Bit more consistent error handling / status updates for Pi GPIO node 2015-02-03 17:22:44 +00:00
Nick O'Leary
07acc6642f Merge pull request #460 from hindessm/fix-lastSent-initial-value
Fix node.lastSent initial value after refactoring.
2015-02-03 13:27:48 +00:00
Nick O'Leary
950611ed31 Merge pull request #554 from hbeeken/Node-spec-fix
Fixing test where part wasn't exercised
2015-02-03 13:26:50 +00:00
dceejay
84e6417877 Change inject node to use tick boxes for days of week instead of select. 2015-02-03 11:21:29 +00:00
hbeeken
a87548a991 Fixing test where part wasn't exercised 2015-02-02 13:21:19 +00:00
dceejay
5e5a220f68 Better ref link for CSS selectors list for HTTP parser node. 2015-01-30 10:00:20 +00:00
dceejay
f451d0644a Allow msg.PATCH method on http request node
Simple fix  to Close PR #524
(no CLA)
2015-01-30 10:00:20 +00:00
Nick O'Leary
e9f0877da8 Skip .info call for subflow IO nodes 2015-01-30 09:53:11 +00:00
dceejay
f6c6301733 Add done() async close to tcp node(s) 2015-01-29 21:43:23 +00:00
dceejay
0709a118e3 more fun trying to close Pi and Arduin nodes async style with done()
(more consistent use of call done().)
2015-01-29 21:43:23 +00:00
Nick O'Leary
7576878ba5 Filter comments when generating palette tooltips
Fixes #549
2015-01-29 21:40:21 +00:00
Nick O'Leary
083e253e45 Configure marked once on start-up 2015-01-29 20:47:30 +00:00
Nick O'Leary
da67e69544 Add drag handle to switch node rules 2015-01-29 20:38:19 +00:00
dceejay
0ed8d28342 Add Markdown capability to Comment node
body is rendered in the info tab and can be styled with Markdown
2015-01-29 18:53:59 +00:00
dceejay
27f9056360 Add status to file node when you overide filename
(so you can see what it writes to... )
2015-01-29 18:53:59 +00:00
dceejay
8c075bfde3 Make HTML select node point to Cheerio select docs. 2015-01-29 18:53:59 +00:00
dceejay
cae755d948 Cleanup closing down of Pi gpio nodes 2015-01-29 18:53:58 +00:00
Nick O'Leary
ca9d84b1b7 Allow Switch rules to be drag-ordered 2015-01-29 16:28:18 +00:00
Nick O'Leary
f983e4da9f Renable unit tests following logging api changes 2015-01-29 09:57:09 +00:00
Nick O'Leary
109270b437 Merge pull request #541 from hbeeken/logging-infrastructure
Adding metric logging mechanism
2015-01-27 17:50:26 +00:00
hbeeken
0bfbb12211 Adding metric logging mechanism 2015-01-27 14:41:20 +00:00
dceejay
69998243cc Add fs.notify, feedparser and serialport to default install packages
To close #518  Pull request 9 by TJ
We want to keep arduino, mongo and redis out of the default install for now.
need for js2xmlparser will go in v0.10
2015-01-21 15:05:35 +00:00
dceejay
8b61c121e6 Small changes to info box language for file watch node 2015-01-21 15:05:35 +00:00
Nick O'Leary
56ef982345 Revert settings.js 2015-01-18 21:24:19 +00:00
Nick O'Leary
8389df9729 Merge branch 'master' of github.com:node-red/node-red 2015-01-18 09:39:05 +00:00
Nick O'Leary
a8f1a6df2c Update sidemenu links to nodered.org 2015-01-18 09:38:47 +00:00
dansu
68e51bb886 added tests for websocket-client
cleanup and prettify
2015-01-18 09:38:47 +00:00
Nick O'Leary
462c259f3a Allow node to provide dynamic content to Info tab
Closes #492

The node definition can now include an `info` property. This property can be either a string or a Function. Whenever the info tab is refreshed, such as the node is selected, the value of this property, or the result of the Function, will be appended to the Info tab.
2015-01-18 09:38:47 +00:00
Nick O'Leary
f6f4b0784b Make subflow delete option more obvious
Fixes #514
2015-01-18 09:38:47 +00:00
Nick O'Leary
57b39022d0 Merge pull request #537 from dsundberg/websocket-client-unittests
added tests for websocket-client
2015-01-17 22:45:22 +00:00
Nick O'Leary
110f0bf169 Allow node to provide dynamic content to Info tab
Closes #492

The node definition can now include an `info` property. This property can be either a string or a Function. Whenever the info tab is refreshed, such as the node is selected, the value of this property, or the result of the Function, will be appended to the Info tab.
2015-01-17 21:36:16 +00:00
Nick O'Leary
3f0fcb70a4 Make subflow delete option more obvious
Fixes #514
2015-01-17 21:02:28 +00:00
Nick O'Leary
d8c7ea8144 Tidy sidebar menu
- remove inconsistent ellipsis
- add Subflow submenu
2015-01-17 20:36:18 +00:00
dansu
44db2c28a3 added tests for websocket-client
cleanup and prettify
2015-01-17 21:10:38 +01:00
Nick O'Leary
8d5f99640e Merge pull request #533 from knolleary/deploy
Add smarter deployment options
2015-01-16 16:00:35 +00:00
Nick O'Leary
ffe417976c Merge pull request #532 from hindessm/random-delay-fixes
Random delay fixes
2015-01-16 15:46:53 +00:00
Nick O'Leary
d04ac00732 Add more Flow_spec tests 2015-01-16 15:43:47 +00:00
Nick O'Leary
dd5e851339 Better sidemenu style 2015-01-16 10:25:57 +00:00
Dave Conway-Jones
2890575b3d Merge pull request #531 from dsundberg/websocket-unittest
Websocket unit tests
2015-01-15 17:18:34 +00:00
Dave Conway-Jones
8b3fbae3f6 Merge pull request #516 from dsundberg/websocket_ext
Added option to specify remote WebSocket URL in web socket node.
2015-01-15 17:17:21 +00:00
Nick O'Leary
c97ab18e62 Add Flow spec 2015-01-15 17:12:50 +00:00
Nick O'Leary
b0ffc12142 Restyle sidebar menu 2015-01-15 10:28:12 +00:00
Nick O'Leary
687a66344e Deploy menu style 2015-01-15 10:28:11 +00:00
Nick O'Leary
a5afc258b1 Update unit tests 2015-01-15 10:28:11 +00:00
Nick O'Leary
afb5e8cbce Fix jshint errors 2015-01-15 10:28:11 +00:00
Nick O'Leary
83b40a7ba6 Fix credential update 2015-01-15 10:28:11 +00:00
Nick O'Leary
cf1371bfdf Add deployment types in runtime
- removes ui option as it needs work
2015-01-15 10:28:11 +00:00
Nick O'Leary
89fff339d5 Add deploy dropdown button 2015-01-15 10:28:10 +00:00
Nick O'Leary
e11abd2508 Identify modified nodes on deploy 2015-01-15 10:28:10 +00:00
dansu
9a0177b900 Added support for websocket-client in 22-wesocket node, selectable in ui
as Listen to/Connect to drop down.
2015-01-15 08:57:42 +01:00
Mark Hindess
5510dffe18 Fix random delay mode to be random delay not random rate-limited stack.
Documentation says "Introduces a delay into a flow or rate limits
messages." but this node was doing delay and rate limit in random mode
which doesn't seem that useful. Worse it was a stack not a queue. I
can't think of any sane use cases for that behaviour.
2015-01-14 14:19:21 +00:00
Mark Hindess
7909ca24d3 Fix random delay in milliseconds case and change test to reproduce bug.
Because there was no multiplier the node.randomFirst was a string so
the later '+' was a concatentation. The test failed to catch this because
it uses integers not strings to configure the node.
2015-01-14 10:18:47 +00:00
dceejay
eee2996e8a Make Pi GPIO node wait for close before restarting
Looking to address Issue #530
2015-01-14 09:55:30 +00:00
dansu
2577631334 Added unittests for websocket node 2015-01-13 10:38:53 +01:00
dansu
9f91493cd1 rename 'send' to 'reply' to not collide with internal node function names, a config node has no wires so the 'send' function gets overwritten with a noop (nodes/red/Node.js:42, introduced in 57ae297) 2015-01-13 08:48:59 +01:00
dceejay
fcec704b7b Reset some changes to sample to be in line with how most of our nodes
actually are.
2015-01-12 19:11:07 +00:00
dceejay
2066d53d3f Handle quotes in JSON inside CSV files in CSV node...
so they come out as real JSON rather than being stripped.
2015-01-09 20:32:05 +00:00
Dave Conway-Jones
8822335700 Merge pull request #522 from motiooon/patch-1
adding skip to the mongodb input node
Great - looks good - many thanks @motiooon
2015-01-09 20:27:09 +00:00
Gabriel Baciu
f461b121e1 mongodb node take a skip property so pagination can be achieved 2015-01-09 14:32:21 -05:00
dceejay
92b393d3df really enforce binary for exec node stdout when required. 2015-01-08 12:35:42 +00:00
dceejay
4fb2a44d74 correct exec binary stdout to be consistent with spawn stdout.
Binary = buffer
String = utf8
2015-01-07 21:33:15 +00:00
dceejay
00429ebe70 Update exec node to handle binary stdout 2015-01-07 21:12:01 +00:00
dceejay
25537e01d4 Add byte mode and mouse buttons to Pi node 2015-01-06 22:06:28 +00:00
Nick O'Leary
65e4d83625 Merge pull request #526 from anna2130/mongo-db-aggregate
Fixed check for array in MongoDB aggregate function
2015-01-05 11:14:18 +00:00
Anna Thomas
ed6272ce12 Fixed check for array in MongoDB aggregate function
Fixes #525
2015-01-05 10:57:49 +00:00
dceejay
9e4187d6a8 New Pi GPIO node based on RPI.GPIO library.
Adds PWM support of outputs and easier access to interrupts for inputs.
2014-12-27 13:11:44 +00:00
Dave C-J
b4dc66944a Make sample node more representaive of a real node...
(OK not really real but at least it now doesn't fail if you try to run it)
2014-12-26 15:28:31 +00:00
Dave C-J
a51056a91f Be a bit more relaxed about IRC node reconnect - it does happen eventually.
Trying to nail down Issue #447
2014-12-18 23:22:36 +00:00
Nick O'Leary
a3692944a2 Merge pull request #515 from anna2130/nr-cli-enhancements
No-op and return success on enabling/disabling node by type name
2014-12-17 14:03:38 +00:00
Anna Thomas
03765afefa Updated nodes_spec test to no-op when already enabled/disabled by type name 2014-12-17 13:58:49 +00:00
Anna Thomas
66213d151d No-op and return success on enabling/disabling node by type name 2014-12-17 13:35:57 +00:00
Nick O'Leary
0c699ae57f Merge pull request #511 from anna2130/nr-cli-enhancements
Updates to match cli changes
2014-12-17 13:10:49 +00:00
Dave C-J
bf8d549cf7 Add "advanced" options to XML parsing node
Allows setting of attrkey and charkey
Push to close #348
2014-12-15 17:05:18 +00:00
Dave C-J
1261bf97ea Remove : from inject node label - people didn't like it.
Claim they can tell the difference between topic and payload as they wrote
the flow...
2014-12-15 17:03:18 +00:00
Dave C-J
41552625e0 remove spurious line of debug from http node 2014-12-15 17:01:58 +00:00
Dave C-J
27ef7d972f Add Binary paylaod option to Http request node
Also add JSON parse option to output
Allow user to select override using msg.method to stop getting warning.
Fix to close #399
2014-12-09 14:40:03 +00:00
Dave C-J
6fc3aab907 Make Palette search Case InSeNsItIve
fix to close #496
2014-12-09 14:37:32 +00:00
Anna Thomas
10681f97d9 Updated tests to reflect addition of version getSet 2014-12-08 16:53:06 +00:00
Anna Thomas
475d9e110e Updated to match cli changes 2014-12-08 16:53:06 +00:00
Nick O'Leary
8c5fab61e6 Merge pull request #509 from anna2130/nr-cli-enhancements
nr-cli enhancements
2014-12-08 13:08:58 +00:00
Anna Thomas
e7ccff5a4b Get version from pkg 2014-12-08 10:15:21 +00:00
Anna Thomas
81e08e06e4 Updated test to reflect saving settings in nodes 2014-12-08 10:10:16 +00:00
Anna Thomas
b006ccf610 saveNodeList saves settings in nodes 2014-12-08 09:57:17 +00:00
Anna Thomas
bb0e48f271 Store version in settings 2014-12-08 09:55:51 +00:00
Nick O'Leary
6d0dffcdf7 Migrate node config to new format 2014-12-05 20:43:41 +00:00
Nick O'Leary
14b84f0c7b Merge pull request #498 from anna2130/nr-cli-enhancements
nr-cli enhancements - server side api
2014-12-05 20:39:42 +00:00
Anna Thomas
8b6e287a74 Updated remove modules tests to reflect getNodeModuleInfo changes 2014-12-05 16:51:26 +00:00
Anna Thomas
1a5751ff1d Update removeModule to reflect getNodeModuleInfo changes 2014-12-05 16:45:32 +00:00
Anna Thomas
851048077c Remove new lines from version 2014-12-04 13:22:42 +00:00
Dave C-J
5f74a1d237 Update file, http and email nodes to only show deprecation warning
if msg property is a real overide  to node property ( !== ).

Fix for comment by @drJeckyll  to Issue #399
2014-12-01 22:58:25 +00:00
Dave Conway-Jones
e9b1e287ba Merge pull request #500 from jacktech24/master
Fixed bug, in Arduino output node
2014-11-28 10:52:12 +00:00
Nick O'Leary
da7b3ce9e4 Incorrect reference to routes in http in node
Fixes #503
2014-11-28 10:09:38 +00:00
Anna Thomas
35b3912808 Removed CLI from repo 2014-11-28 09:21:39 +00:00
Anna Thomas
e28f933f64 Refactor saveNodeList 2014-11-28 09:17:46 +00:00
Anna Thomas
57bc83b2a7 Enabling and disabling non-existent nodes throws an error 2014-11-27 16:42:45 +00:00
Anna Thomas
ec43fc4fe2 Removed unused code 2014-11-27 13:12:47 +00:00
Anna Thomas
8f2a0b63d9 Changed cleanNodeList to cleanModuleList 2014-11-26 16:46:51 +00:00
Anna Thomas
bb6e27f662 Store node list as module list 2014-11-26 16:25:37 +00:00
jacktech24
4e28a308b0 fixed bug, replaced servoWrite with analogWrite where it should be 2014-11-25 20:42:17 +01:00
Anna Thomas
04ffaeb2b8 Refactor nodeModules.nodes to moduleNodes 2014-11-24 15:44:11 +00:00
Anna Thomas
d7f249eac4 Added version number to modules 2014-11-21 16:35:29 +00:00
Anna Thomas
a5064b3ab6 Reloads module info after enabling/disabling module 2014-11-21 16:34:57 +00:00
Anna Thomas
dd5821ee1b Installing a module returns module info
Removing a module checks module exists and checks type is not in use
2014-11-21 15:15:24 +00:00
Anna Thomas
4c9d53388c Removed plugins references 2014-11-21 11:31:07 +00:00
Anna Thomas
70f101497d Replaced delete response with 204 2014-11-21 11:25:51 +00:00
Anna Thomas
56cb985de9 Separated put response into /nodes/:mod and /nodes/:mod/:set
Updated put tests
2014-11-21 10:36:32 +00:00
Anna Thomas
d614b7c39f Moved get node set response to /nodes/:mod/:set
Updated tests
Changed plugin back to module
2014-11-20 15:18:16 +00:00
Anna Thomas
0ff65f6805 Updated registry tests to reflect id changes 2014-11-20 13:08:27 +00:00
Anna Thomas
591b5f3f91 Replaced hex id with 'module/set' id 2014-11-20 12:15:15 +00:00
Anna Thomas
50fddf474b Local nodes loaded with node-red as their module 2014-11-20 09:58:42 +00:00
Nick O'Leary
3a78a2fedd Tab name changes not persisting
Fixes #495
2014-11-19 16:03:12 +00:00
Anna Thomas
9552055b08 loadNodeConfig assumed to always be called with module and name parameters 2014-11-19 13:54:00 +00:00
Nick O'Leary
71bd5cd9e9 Merge pull request #485 from anna2130/nr-cli-enhancements
WIP: Command Line Tool API
2014-11-17 13:34:24 +00:00
Nick O'Leary
7cff7ed297 Merge pull request #491 from anna2130/mongo-msg-collection
Fixes collection only being set by first message
2014-11-17 11:15:45 +00:00
Anna Thomas
6ba0d83778 Fixes collection only being set by first message 2014-11-17 10:33:31 +00:00
Dave C-J
ca2ef7e71f Pi GPIO node was not displaying Model B+ pin numbers correctly
on subsequent edit.
2014-11-16 18:23:24 +00:00
Dave C-J
977a9e1c83 Better attempt at making Inject node label more "useful".
Addresses Issue #489
2014-11-16 18:22:33 +00:00
Dave C-J
7da108e129 Reverting fix for #489 while we debate the issue more fully.... 2014-11-14 23:50:49 +00:00
Dave C-J
7b14e753cd Let Twitter node save place as a location property rather than text. 2014-11-14 23:42:35 +00:00
Dave C-J
9863b6e178 Add payload to Inject label to make more helpful
Close #489
2014-11-14 17:28:08 +00:00
Nick O'Leary
0789b82c15 Restore dialog size on reopn properly 2014-11-13 22:14:05 +00:00
Nick O'Leary
a477c0b827 Fix serial config node edit layout 2014-11-13 20:53:15 +00:00
Nick O'Leary
3cb423a0b4 Fix func/temp/comment editor resizing 2014-11-13 17:21:12 +00:00
Nick O'Leary
9c8d9550a7 Do not assume subflows exist when deleting nodes 2014-11-13 16:00:46 +00:00
Anna Thomas
8d16f3c8be Registry tests for plugins and enable/disable in CLI 2014-11-13 15:14:20 +00:00
Nick O'Leary
b4c92b457a Flatten the dialog box style 2014-11-13 13:55:12 +00:00
Nick O'Leary
426fcc2fdd Rework subflow edit process 2014-11-13 12:59:28 +00:00
Nick O'Leary
5cb9a5b7eb All subflow input to be deleted by selection 2014-11-13 00:02:41 +00:00
Nick O'Leary
64a6fe11da Add subflow outputs to be delete by selection 2014-11-12 23:51:42 +00:00
Nick O'Leary
f72f7cdaa7 Merge pull request #469 from Belphemur/ui-localstorage
Ui localstorage
2014-11-11 10:43:06 +00:00
Antoine Aflalo
01f0d5390f Adding support to LocalStorage on client side
Save the state of the Menu Item between session (like activation of
node-status and sidebar)
2014-11-11 09:04:57 +02:00
Dave C-J
ed9951f065 Add PWM support to Pi GPIO Node - pin 12 (GPIO1)
(only pin that has hardware pwm support)

Note: It will interfere with any other audio output as they share 
same hardware/timers.
2014-11-10 20:03:51 +00:00
Nick O'Leary
4249cf5d69 Fix debugMaxLength description
Closes #484
2014-11-09 20:55:13 +00:00
Dave C-J
5da45b404c Add delete option to File node
to replace msg.delete option - now deprecated but not removed.
Addresses some of the confusion  for Issue #399
2014-11-08 15:34:54 +00:00
Dave C-J
8b7e367416 tweak CSV parser to better handle GSM style phone numbers. 2014-11-08 15:34:54 +00:00
Nick O'Leary
28da2dc38a Subflow palette node outputs not updating
part of #479
2014-11-07 16:12:27 +00:00
Dave C-J
5c5de028da Add remote server name to page title / tab
Makes selecting one of several servers easier.
2014-11-07 12:28:35 +00:00
Dave C-J
b861f490c6 tiny tidy-up on TCP request node 2014-11-07 12:28:34 +00:00
Nick O'Leary
e7dccf04d2 Changing subflow in/outs leaving wires behind
Fixes #477
2014-11-07 11:22:00 +00:00
Nick O'Leary
3e235ecc0b Move cloneMessage to RED.util.cloneMessage 2014-11-06 11:39:30 +00:00
Anna Thomas
deeaa09360 Renamed modules to plugins for CLI 2014-11-06 10:59:34 +00:00
Anna Thomas
2e7a97fb88 Get plugins tests 2014-11-06 10:59:06 +00:00
Dave C-J
9c92eeb9f5 Allow tcp request node to accept msg.host and msg.port as inputs
Overrides only allowed if edit setting left blank.
2014-11-06 10:21:14 +00:00
Anna Thomas
3e24601518 Functionality to get installed module info from the cli 2014-11-06 10:00:25 +00:00
Nick O'Leary
266a644ca6 Preserve querystring when ensuring path ends with slash 2014-11-06 00:01:01 +00:00
Nick O'Leary
def93214de Merge pull request #476 from knolleary/auth
Reorganise how adminApp is setup
2014-11-05 23:18:32 +00:00
Nick O'Leary
a520240b25 Ensure application/json on library flows reqs 2014-11-05 23:08:23 +00:00
Nick O'Leary
e7eb02fcb7 Add unit tests for refactored API modules 2014-11-05 23:07:50 +00:00
Nick O'Leary
72f9471f2b Reorganise how adminApp is setup 2014-11-05 22:45:18 +00:00
Nick O'Leary
67449eb65a Merge pull request #470 from anna2130/msg-property-overrides
Message properties overriding set node properties
2014-11-05 22:05:34 +00:00
Anna Thomas
069a47f35a Added node warnings when message properties override set node properties 2014-11-05 17:23:27 +00:00
Nick O'Leary
53b07581cf Merge pull request #474 from zobalogh/twitter-location
Adding location support to Twitter
2014-11-05 15:40:47 +00:00
zobalogh
11a29b4633 Adding location support to Twitter 2014-11-05 12:00:37 +00:00
Dave C-J
bdb46cbbe4 Add "is-utf8" npm to package - part of fix #435 2014-11-04 22:00:58 +00:00
Dave C-J
273acc0ec4 Let MQTT input node receive binary packets
Try to auto select output type to be string or buffer to be backwards compatible
Fixes #435
2014-11-04 21:56:15 +00:00
Nick O'Leary
1153619a03 Handle uninitialised node in single-wire fastpath 2014-11-04 11:36:28 +00:00
Nick O'Leary
f89ddb5f7a Merge pull request #463 from njh/redis-object
Added support for storing a msg.payload of type object in a Redis hash
2014-11-01 21:19:45 +00:00
Nick O'Leary
4494c11b03 Subflow name property getting dropped on import
Closes #468
2014-10-31 22:46:26 +00:00
Dave C-J
694649e8f9 Update feedparse in line with underlying npm. 2014-10-31 18:59:57 +00:00
Anna Thomas
9f925140c9 Updated MongoDB node info 2014-10-31 15:41:13 +00:00
Nick O'Leary
6a37a823df Update orion to 7.0 release
Closes #467

Version: http://download.eclipse.org/orion/drops/R-7.0-201410282256/index.html
2014-10-31 14:28:33 +00:00
Nick O'Leary
f0e9a0279f Ignore comms heartbeat messages in comms test 2014-10-31 13:06:08 +00:00
Nick O'Leary
863b85714d localfilesystem storage must fsync writes
Closes #465
2014-10-31 11:40:10 +00:00
Nick O'Leary
dfc79e3122 Preserve unknown node type properties across deploys
Closes #5
2014-10-30 21:41:42 +00:00
Nicholas Humfrey
afde3d0ab8 Added support for storing a msg.payload of type object in a Redis hash 2014-10-30 10:09:40 +00:00
Nick O'Leary
7419f62a20 Merge pull request #461 from hindessm/fix-tweet-post-error-reporting
Fix tweet post error reporting.
2014-10-30 08:44:08 +00:00
Mark Hindess
f06b52625f Fix tweet post error reporting. 2014-10-30 08:38:49 +00:00
Nick O'Leary
ccfbd69f24 Merge pull request #459 from hindessm/fix-info-id-refactoring-bug
Fix refactoring error; rename info to id.
2014-10-30 08:35:10 +00:00
Mark Hindess
d859412785 Fix node.lastSent initial value after refactoring. 2014-10-30 08:19:52 +00:00
Mark Hindess
3840bd117c Fix refactoring error; rename info to id. 2014-10-30 08:08:41 +00:00
Nick O'Leary
aff8a7802a Merge pull request #458 from knolleary/subflows
Add Subflows
2014-10-29 22:04:48 +00:00
Nick O'Leary
6169e4299a Add initial subflow tests 2014-10-29 21:44:33 +00:00
Nick O'Leary
d9648ca76b Add subflow support 2014-10-29 20:26:25 +00:00
Dave C-J
348b642d25 Return sensible name to display for Delay node Queue mode 2014-10-29 18:26:43 +00:00
Dave C-J
a1830def8e Fix http in node close wrinkle if cors enabled but not used. 2014-10-29 18:26:09 +00:00
Dave C-J
98b875c4a0 Neater fix for Mac meta key - thanks to Nick. 2014-10-29 09:05:48 +00:00
Nick O'Leary
d242f67be3 Merge pull request #457 from anna2130/change-node-multi-level-properties
Change node can set msg property to another msg property. Closes #456
2014-10-28 16:07:42 +00:00
Anna Thomas
ce6513e7f7 Change node can set msg property to another msg property. Closes #456 2014-10-28 15:50:50 +00:00
Dave C-J
bd75c1c753 Better attempt at adding Apple meta key 2014-10-28 09:03:00 +00:00
Nick O'Leary
48d3b8f37a Inject node interval error
part two of #455
2014-10-27 19:41:29 +00:00
Nick O'Leary
4c573b208c Merge branch 'master' of github.com:node-red/node-red 2014-10-27 19:36:43 +00:00
Nick O'Leary
a5228875a6 Inject node calculating hour interval period incorrectly
Fixes #455
2014-10-27 19:36:26 +00:00
Dave C-J
c51866c2c5 Add ⌘ Cmd key as alternative to Ctrl key to make Mac users happy. 2014-10-27 15:07:34 +00:00
Dave C-J
bbaf7bf247 correcting typos in trigger node... oops 2014-10-27 08:54:21 +00:00
Nick O'Leary
04673c65f4 Node drag start threshold incorrectly calculated 2014-10-26 22:23:56 +00:00
Nick O'Leary
57ae297efd Clone messages before any node.receive call 2014-10-25 23:12:30 +01:00
Dave C-J
0bb78ae491 Try to ensure TCP node closes server connections on redeploy
(to clean up properly - especially in case of port changes)

Closes Issue #454
2014-10-25 17:52:24 +01:00
Dave C-J
d9363f4974 Reduce logging for exec node
(can be re-enabled by using node -v red.js ... )
2014-10-25 17:50:55 +01:00
Dave C-J
b54e9edfa6 Add "topic based fair queue" option to delay node 2014-10-24 20:00:25 +01:00
Dave C-J
cf81de415a Minor UI tweaks to RPi node 2014-10-24 20:00:25 +01:00
Nick O'Leary
4cd78692e2 Handle debug boolean complete properties 2014-10-23 15:28:47 +01:00
Nick O'Leary
5fd1ff5137 Add hint on requiring fs module in settings.js 2014-10-22 21:44:01 +01:00
Nick O'Leary
fe95a98339 Merge pull request #441 from anna2130/reduce-message-cloning-overhead
Reduces message cloning overhead for single recipients
2014-10-22 15:09:59 +01:00
Nick O'Leary
da73972c41 Merge pull request #449 from hbeeken/update-test-helper
Adding capability to the test helper to load more than one node at once
2014-10-22 15:08:17 +01:00
Nick O'Leary
014389c55f Merge pull request #450 from Belphemur/patch-1
Correcting a Typo
2014-10-22 15:07:47 +01:00
Antoine Aflalo
ff4edccbbc Correcting a Typo 2014-10-22 16:33:48 +03:00
hbeeken
1e7ce2cfe7 Adding capability to the test helper to load more than one node at once 2014-10-22 11:29:54 +01:00
Anna Thomas
bc8e459ae6 Node does not clone first message sent
Tests updated to mirror this behaviour
    Annotated algorithm
2014-10-21 14:08:35 +01:00
Nick O'Leary
53a9a5fe93 Merge pull request #422 from anna2130/debug
Updated debug node to output other msg properties
2014-10-20 16:35:24 +01:00
Anna Thomas
17e4bf1a11 Tidy up node label and edit dialog 2014-10-20 12:52:07 +01:00
Nick O'Leary
bec4e429f9 Merge pull request #433 from anna2130/change-node-multi-level-properties
Change node: Multi-level properties
2014-10-20 11:12:59 +01:00
Dave C-J
472fdc65a9 Allow Raspberry Pi node to set initial output level.
Fix for #443
Also allow (optional) initial read of input pins on deploy.
Moved to Category Raspberry Pi 
(other Pi related nodes will be updated to match soon).
2014-10-19 13:54:21 +01:00
Dave C-J
28a4ba1aad Don't let IRC node try to join channels multiple times...
Addresses #447
2014-10-18 20:38:58 +01:00
Dave Conway-Jones
dd9fc6a250 Merge pull request #437 from hindessm/file-query-node-usability
Minor fixes to messages sent from "file in" nodes.
2014-10-14 17:54:47 +01:00
Dave C-J
7802939bb0 fix IRC node (once again)
refactoring created incorrect object references - which weren't picked up.
(sorry) -  Addresses Issue 439
2014-10-09 20:50:46 +01:00
Nick O'Leary
d4a21be666 Clone settings to avoid modifying original values 2014-10-09 14:21:53 +01:00
Mark Hindess
0d9abbb8b6 Minor fixes to messages sent from "file in" nodes.
Specifically:

* in the error case, set msg.filename to be the name of the file used (as
  is done in the non-error case),

* in the error case, delete msg.payload so that subsequent nodes only need
  check for a msg.payload to act upon if they don't care about error cases,
  and

* in the non-error case, delete msg.error to avoid passing through errors
  from earlier nodes to a subsequent node that does care about error cases

Messages sent will now always have well-defined behaviour with respect to
the payload, filename, and error in both error and non-error cases.
2014-10-09 11:19:14 +01:00
Nick O'Leary
9a32e79603 Merge pull request #436 from anna2130/calculate-text-width
Refactored palette.js and view.js to reuse calculateTextWidth
2014-10-09 10:21:42 +01:00
Anna Thomas
206b8ac34a Refactored to reuse calculateTextWidth 2014-10-09 10:07:17 +01:00
Anna Thomas
986ce8163f Added tests to check functionality when using multi-level properties 2014-10-07 16:12:35 +01:00
Anna Thomas
97e5c2e571 Added multi-level property functionality 2014-10-07 16:12:35 +01:00
Anna Thomas
2a753c9d22 Updated debug node test 2014-10-07 10:25:56 +01:00
Anna Thomas
f96b40cff2 Updated debug node to output other msg properties 2014-10-07 10:25:56 +01:00
379 changed files with 39128 additions and 15346 deletions

22
.gitignore vendored
View File

@@ -1,9 +1,19 @@
node_modules
.DS_store
.config.json
.dist
.jshintignore
.npm
.project
.sessions.json
.settings
.tern-project
*.backup
*_cred*
coverage
credentials.json
flows*.json
flows.backup
*_cred*
nodes/node-red-nodes/
.npm
/coverage
.config.json
node_modules
public
locales/zz-ZZ
nodes/core/locales/zz-ZZ

13
.jshintrc Normal file
View File

@@ -0,0 +1,13 @@
{
"asi": true, // allow missing semicolons
"curly": true, // require braces
"eqnull": true, // ignore ==null
"forin": true, // require property filtering in "for in" loops
"immed": true, // require immediate functions to be wrapped in ( )
"nonbsp": true, // warn on unexpected whitespace breaking chars
//"strict": true, // commented out for now as it causes 100s of warnings, but want to get there eventually
//"unused": true, // Check for unused functions and variables
"loopfunc": true, // allow functions to be defined in loops
//"expr": true, // allow ternery operator syntax...
"sub": true // don't warn that foo['bar'] should be written as foo.bar
}

View File

@@ -1,4 +1,5 @@
.git/*
*.json
lib/*
/Gruntfile.js
/.git/*
/lib/*
*.backup
/public/*

7
.npmignore Normal file
View File

@@ -0,0 +1,7 @@
.settings
.jshintignore
.jshintrc
.project
.tern-project
.travis.yml
.git

View File

@@ -1,9 +1,24 @@
sudo: false
language: node_js
env:
- CXX="g++-4.8"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
- gcc-4.8
matrix:
allow_failures:
- node_js: "5"
before_install:
- npm install -g npm@~1.4.18
- npm install -g npm@latest-2
node_js:
- "5"
- "4"
- "0.12"
- "0.10"
- "0.8"
script:
- istanbul cover ./node_modules/.bin/grunt --report lcovonly && istanbul report text && ( cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js || true ) && rm -rf coverage
before_script:

View File

@@ -2,10 +2,14 @@
We welcome contributions, but request you follow these guidelines.
- [Raising issues](#raising-issues)
- [Feature requests](#feature-requests)
- [Pull-Requests](#pull-requests)
- [Contributor License Agreement](#contributor-license-agreement)
## Raising issues
Please raise any bug reports on the project's
[issue tracker](https://github.com/node-red/node-red/issues?state=open). Be sure to
Please raise any bug reports on the relevant project's issue tracker. Be sure to
search the list to see if your issue has already been raised.
A good bug report is one that make it easy for us to understand what you were
@@ -20,50 +24,22 @@ At a minimum, please include:
- Version of Node-RED - either release number if you downloaded a zip, or the first few lines of `git log` if you are cloning the repository directly.
- Version of node.js - what does `node -v` say?
## New features
## Feature requests
For feature requests, please raise them on the [mailing list](https://groups.google.com/forum/#!forum/node-red).
## Pull-Requests
### Changes to existing code
if you want to raise a pull-request with a new feature, or a refactoring
of existing code, it may well get rejected if you haven't discussed it on
If you want to raise a pull-request with a new feature, or a refactoring
of existing code, it may well get rejected if you haven't discussed it on
the [mailing list](https://groups.google.com/forum/#!forum/node-red) first.
### New nodes
The plugin nature of Node-RED means anyone can create a new node to extend
its capabilities.
We want to avoid duplication as that can lead to confusion. Many of our existing
nodes offer a starting point of functionality. If they are missing features,
we would rather extend them than add separate 'advanced' versions. But the key
to that approach is getting the UX right to not lose the simplicity.
To contribute a new node, please raise a pull-request against the
`node-red-nodes` repository.
Eventually, the nodes will be npm-installable, but we're not there yet. We'll
also have some sort of registry of nodes to help with discoverability.
### Coding standards
Please ensure you follow the coding standards used through-out the existing
code base. Some basic rules include:
- all files must have the Apache license in the header.
- indent with 4-spaces, no tabs. No arguments.
- opening brace on same line as `if`/`for`/`function`/etc, closing brace on its
own line.
### Contributor License Aggreement
### Contributor License Agreement
In order for us to accept pull-requests, the contributor must first complete
a Contributor License Agreement (CLA). This clarifies the intellectual
property license granted with any contribution. It is for your protection as a
Contributor as well as the protection of IBM and its customers; it does not
a Contributor License Agreement (CLA). This clarifies the intellectual
property license granted with any contribution. It is for your protection as a
Contributor as well as the protection of IBM and its customers; it does not
change your rights to use your own Contributions for any other purpose.
You can download the CLAs here:
@@ -74,9 +50,12 @@ You can download the CLAs here:
If you are an IBMer, please contact us directly as the contribution process is
slightly different.
### Coding standards
Please ensure you follow the coding standards used through-out the existing
code base. Some basic rules include:
- all files must have the Apache license in the header.
- indent with 4-spaces, no tabs. No arguments.
- opening brace on same line as `if`/`for`/`function` and so on, closing brace
on its own line.

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2013, 2014 IBM Corp.
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,78 +14,410 @@
* limitations under the License.
**/
var path = require("path");
module.exports = function(grunt) {
// Project configuration.
var nodemonArgs = ["-v"];
var flowFile = grunt.option('flowFile');
if (flowFile) {
nodemonArgs.push(flowFile);
}
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
simplemocha: {
options: {
globals: ['expect'],
timeout: 3000,
ignoreLeaks: false,
ui: 'bdd',
reporter: 'spec'
},
all: { src: ['test/**/*_spec.js'] },
core: { src: ["test/_spec.js","test/red/**/*_spec.js"]},
nodes: { src: ["test/nodes/**/*_spec.js"]}
pkg: grunt.file.readJSON('package.json'),
paths: {
dist: ".dist"
},
simplemocha: {
options: {
globals: ['expect'],
timeout: 3000,
ignoreLeaks: false,
ui: 'bdd',
reporter: 'spec'
},
jshint: {
options: {
// http://www.jshint.com/docs/options/
"asi": true, // allow missing semicolons
"curly": true, // require braces
"eqnull": true, // ignore ==null
"forin": true, // require property filtering in "for in" loops
"immed": true, // require immediate functions to be wrapped in ( )
"nonbsp": true, // warn on unexpected whitespace breaking chars
//"strict": true, // commented out for now as it causes 100s of warnings, but want to get there eventually
"loopfunc": true, // allow functions to be defined in loops
"sub": true // don't warn that foo['bar'] should be written as foo.bar
},
all: [
'Gruntfile.js',
'red.js',
'red/**/*.js',
'nodes/**/*.js',
'public/red/**/*.js'
],
core: {
files: {
src: [
'Gruntfile.js',
'red.js',
'red/**/*.js'
]
}
},
nodes: {
files: {
src: [ 'nodes/**/*.js' ]
}
},
editor: {
files: {
src: [ 'public/red/**/*.js' ]
}
},
tests: {
files: {
src: ['test/**/*.js']
},
options: {
"expr": true
}
all: { src: ['test/**/*_spec.js'] },
core: { src: ["test/_spec.js","test/red/**/*_spec.js"]},
nodes: { src: ["test/nodes/**/*_spec.js"]}
},
jshint: {
options: {
jshintrc:true
// http://www.jshint.com/docs/options/
//"asi": true, // allow missing semicolons
//"curly": true, // require braces
//"eqnull": true, // ignore ==null
//"forin": true, // require property filtering in "for in" loops
//"immed": true, // require immediate functions to be wrapped in ( )
//"nonbsp": true, // warn on unexpected whitespace breaking chars
////"strict": true, // commented out for now as it causes 100s of warnings, but want to get there eventually
//"loopfunc": true, // allow functions to be defined in loops
//"sub": true // don't warn that foo['bar'] should be written as foo.bar
},
all: [
'Gruntfile.js',
'red.js',
'red/**/*.js',
'nodes/core/*/*.js',
'editor/js/**/*.js'
],
core: {
files: {
src: [
'Gruntfile.js',
'red.js',
'red/**/*.js'
]
}
},
nodes: {
files: {
src: [ 'nodes/core/*/*.js' ]
}
},
editor: {
files: {
src: [ 'editor/js/**/*.js' ]
}
},
tests: {
files: {
src: ['test/**/*.js']
},
options: {
"expr": true
}
}
},
concat: {
options: {
separator: ";",
},
build: {
src: [
// Ensure editor source files are concatenated in
// the right order
"editor/js/main.js",
"editor/js/events.js",
"editor/js/i18n.js",
"editor/js/settings.js",
"editor/js/user.js",
"editor/js/comms.js",
"editor/js/ui/state.js",
"editor/js/nodes.js",
"editor/js/history.js",
"editor/js/validators.js",
"editor/js/ui/deploy.js",
"editor/js/ui/menu.js",
"editor/js/ui/keyboard.js",
"editor/js/ui/tabs.js",
"editor/js/ui/popover.js",
"editor/js/ui/workspaces.js",
"editor/js/ui/view.js",
"editor/js/ui/sidebar.js",
"editor/js/ui/palette.js",
"editor/js/ui/tab-info.js",
"editor/js/ui/tab-config.js",
"editor/js/ui/editor.js",
"editor/js/ui/clipboard.js",
"editor/js/ui/library.js",
"editor/js/ui/notifications.js",
"editor/js/ui/subflow.js",
"editor/js/ui/touch/radialMenu.js"
],
dest: "public/red/red.js"
},
vendor: {
files: {
"public/vendor/vendor.js": [
"editor/vendor/jquery/js/jquery-1.11.1.min.js",
"editor/vendor/bootstrap/js/bootstrap.min.js",
"editor/vendor/jquery/js/jquery-ui-1.10.3.custom.min.js",
"editor/vendor/jquery/js/jquery.ui.touch-punch.min.js",
"editor/vendor/marked/marked.min.js",
"editor/vendor/orion/built-editor.min.js",
"editor/vendor/d3/d3.v3.min.js",
"editor/vendor/i18next/i18next.min.js"
],
"public/vendor/vendor.css": [
"editor/vendor/orion/built-editor.css"
// TODO: resolve relative resource paths in
// bootstrap/FA/jquery
]
}
}
},
uglify: {
build: {
files: {
'public/red/red.min.js': 'public/red/red.js'
}
}
},
sass: {
build: {
options: {
outputStyle: 'compressed'
},
files: [{
dest: 'public/red/style.min.css',
src: 'editor/sass/style.scss'
},
{
dest: 'public/vendor/bootstrap/css/bootstrap.min.css',
src: 'editor/vendor/bootstrap/css/bootstrap.css'
}]
}
},
jsonlint: {
messages: {
src: [
'nodes/core/locales/en-US/messages.json',
'locales/en-US/editor.json',
'locales/en-US/runtime.json'
]
}
},
attachCopyright: {
js: {
src: [
'public/red/red.min.js'
]
},
css: {
src: [
'public/red/style.min.css'
]
}
},
clean: {
build: {
src: [
"public/red",
"public/index.html",
"public/favicon.ico",
"public/icons",
"public/vendor"
]
},
release: {
src: [
'<%= paths.dist %>'
]
}
},
watch: {
js: {
files: [
'editor/js/**/*.js'
],
tasks: ['concat','uglify','attachCopyright:js']
},
sass: {
files: [
'editor/sass/**/*.scss'
],
tasks: ['sass','attachCopyright:css']
},
json: {
files: [
'nodes/core/locales/en-US/messages.json',
'locales/en-US/editor.json',
'locales/en-US/runtime.json'
],
tasks: ['jsonlint:messages']
}
},
nodemon: {
/* uses .nodemonignore */
dev: {
script: 'red.js',
options: {
args: nodemonArgs,
ext: 'js,html,json',
watch: [
'red','nodes','locales'
]
}
}
},
concurrent: {
dev: {
tasks: ['nodemon', 'watch'],
options: {
logConcurrentOutput: true
}
}
},
copy: {
build: {
files:[{
cwd: 'editor/images',
src: '**',
expand: true,
dest: 'public/red/images/'
},
{
cwd: 'editor/vendor',
src: [
'ace/**',
//'bootstrap/css/**',
'bootstrap/img/**',
'jquery/css/**',
'font-awesome/**'
],
expand: true,
dest: 'public/vendor/'
},
{
cwd: 'editor/icons',
src: '**',
expand: true,
dest: 'public/icons/'
},
{
expand: true,
src: ['editor/index.html','editor/favicon.ico'],
dest: 'public/',
flatten: true
}]
},
release: {
files: [{
mode: true,
expand: true,
src: [
'*.md',
'LICENSE',
'package.json',
'settings.js',
'red.js',
'lib/.gitignore',
'nodes/*.demo',
'nodes/core/**',
'red/**',
'public/**',
'editor/templates/**',
'bin/**',
'locales/**'
],
dest: path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>')
}]
}
},
chmod: {
options: {
mode: '755'
},
release: {
// Target-specific file/dir lists and/or options go here.
src: [
path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/nodes/core/hardware/nrgpio*')
]
}
},
compress: {
release: {
options: {
archive: '<%= paths.dist %>/node-red-<%= pkg.version %>.zip'
},
expand: true,
cwd: '<%= paths.dist %>/',
src: ['node-red-<%= pkg.version %>/**']
}
}
});
grunt.loadNpmTasks('grunt-simple-mocha');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('default', ['jshint:core','jshint:tests','jshint:editor','simplemocha:core','simplemocha:nodes']);
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-nodemon');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-chmod');
grunt.loadNpmTasks('grunt-jsonlint');
grunt.registerMultiTask('attachCopyright', function() {
var files = this.data.src;
var copyright = "/**\n"+
" * Copyright 2013, 2015 IBM Corp.\n"+
" *\n"+
" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"+
" * you may not use this file except in compliance with the License.\n"+
" * You may obtain a copy of the License at\n"+
" *\n"+
" * http://www.apache.org/licenses/LICENSE-2.0\n"+
" *\n"+
" * Unless required by applicable law or agreed to in writing, software\n"+
" * distributed under the License is distributed on an \"AS IS\" BASIS,\n"+
" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"+
" * See the License for the specific language governing permissions and\n"+
" * limitations under the License.\n"+
" **/\n";
if (files) {
for (var i=0;i<files.length;i++) {
var file = files[i];
if (!grunt.file.exists(file)) {
grunt.log.warn('File '+ file + ' not found');
return false;
} else {
var content = grunt.file.read(file);
if (content.indexOf(copyright) == -1) {
content = copyright+content;
if (!grunt.file.write(file, content)) {
return false;
}
grunt.log.writeln("Attached copyright to "+file);
} else {
grunt.log.writeln("Copyright already on "+file);
}
}
}
}
});
grunt.registerTask('setDevEnv',
'Sets NODE_ENV=development so non-minified assets are used',
function () {
process.env.NODE_ENV = 'development';
});
grunt.registerTask('default',
'Builds editor content then runs code style checks and unit tests on all components',
['build','test-core','test-editor','test-nodes']);
grunt.registerTask('test-core',
'Runs code style check and unit tests on core runtime code',
['jshint:core','simplemocha:core']);
grunt.registerTask('test-editor',
'Runs code style check on editor code',
['jshint:editor']);
grunt.registerTask('test-nodes',
'Runs unit tests on core nodes',
['simplemocha:nodes']);
grunt.registerTask('build',
'Builds editor content',
['clean:build','concat:build','concat:vendor','uglify:build','sass:build','jsonlint:messages','copy:build','attachCopyright']);
grunt.registerTask('dev',
'Developer mode: run node-red, watch for source changes and build/restart',
['build','setDevEnv','concurrent:dev']);
grunt.registerTask('release',
'Create distribution zip file',
['build','clean:release','copy:release','chmod:release','compress:release']);
};

View File

@@ -1,57 +0,0 @@
Node-RED Install
================
## Install node.js
You can get the latest version from <http://nodejs.org/download/>.
Or, you may want to use a version from your operating system's package manager:
<https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager>
## Get Node-RED
Clone the repository from GitHub:
$ git clone git@github.com:node-red/node-red.git
## Install the pre-requisite modules
From the top-level directory of Node-RED, run:
$ npm install
This will install the core pre-requisite modules.
## Run Node-RED
From the top-level directory, run:
$ node red.js
You can then access Node-RED at <http://localhost:1880>.
Online documentation is available at <http://nodered.org/docs>.
## Installing individual node dependencies
When Node-RED starts, it attempts to load the nodes from the `nodes/` directory.
Each will have its own set of dependencies that will need to be installed before
the node is available in the palette.
To help identify the dependencies, Node-RED logs any modules it fails to find
for a particular node. You don't have to install these unless you want or need
that node to appear.
Alternatively, a node's `.js` file can be examined to identify the modules it
explicitly requires. For example, the Twitter node is defined in
`nodes/social/27-twitter.js` and contains:
var RED = require("../../red/red");
var ntwitter = require('ntwitter');
var OAuth= require('oauth').OAuth;
Of these, `ntwitter` and `oauth` are neither built-in modules nor ones provided
by Node-RED itself. They can subsequently be installed by running:
$ npm install ntwitter oauth

View File

@@ -2,40 +2,58 @@
http://nodered.org
[![Build Status](https://travis-ci.org/node-red/node-red.png)](https://travis-ci.org/node-red/node-red) [![Coverage Status](https://coveralls.io/repos/node-red/node-red/badge.png?branch=master)](https://coveralls.io/r/node-red/node-red?branch=master)
[![Build Status](https://travis-ci.org/node-red/node-red.svg)](https://travis-ci.org/node-red/node-red)
[![Coverage Status](https://coveralls.io/repos/node-red/node-red/badge.svg?branch=master)](https://coveralls.io/r/node-red/node-red?branch=master)
A visual tool for wiring the Internet of Things.
![Screenshot](http://nodered.org/images/node-red-screenshot.png "Node-RED: A visual tool for wiring the Internet of Things")
![Node-RED: A visual tool for wiring the Internet of Things](http://nodered.org/images/node-red-screenshot.png)
## Quick Start
Check out [INSTALL](INSTALL.md) for full instructions on getting started.
Check out http://nodered.org/docs/getting-started/ for full instructions on getting
started.
1. download the zip and unzip, or git clone
2. cd node-red
3. npm install
4. node red.js
5. Open <http://localhost:1880>
1. `sudo npm install -g node-red`
2. `node-red`
3. Open <http://localhost:1880>
## Documentation
## Getting Help
More documentation can be found [here](http://nodered.org/docs).
For further help, or general discussion, there is also a [mailing list](https://groups.google.com/forum/#!forum/node-red).
For further help, or general discussion, please use the
[mailing list](https://groups.google.com/forum/#!forum/node-red).
## Browser Support
## Developers
The Node-RED editor runs in the browser. We routinely develop and test using
Chrome and Firefox. We have anecdotal evidence that it works in IE9.
If you want to run the latest code from git, here's how to get started:
We do not yet support mobile browsers, although that is high on our priority
list.
1. Install grunt, the build tool
npm install -g grunt-cli
2. Clone the code:
git clone https://github.com/node-red/node-red.git
cd node-red
3. Install the node-red dependencies
npm install
4. Build the code
grunt build
5. Run
node red.js
## Contributing
Please see our [contributing guide](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md).
Before raising a pull-request, please read our
[contributing guide](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md).
## Authors
@@ -48,4 +66,4 @@ For more open-source projects from IBM, head over [here](http://ibm.github.io).
## Copyright and license
Copyright 2013, 2014 IBM Corp. under [the Apache 2.0 license](LICENSE).
Copyright 2013, 2015 IBM Corp. under [the Apache 2.0 license](LICENSE).

43
bin/node-red-pi Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/bash
#
# Copyright 2015 IBM Corp.
#
# 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.
#
# Separate out node/v8 options from node-red ones
OPTIONS=""
ARGS=""
for arg in "$@"
do
case $arg in
--userDir|--settings|--help) ARGS="$ARGS $arg";;
--*) OPTIONS="$OPTIONS $arg";;
*) ARGS="$ARGS $arg";;
esac
done
# Find the real location of this script
CURRENT_PATH=`pwd`
SCRIPT_PATH="${BASH_SOURCE[0]}";
while([ -h "${SCRIPT_PATH}" ]); do
cd "`dirname "${SCRIPT_PATH}"`"
SCRIPT_PATH="$(readlink "`basename "${SCRIPT_PATH}"`")";
done
cd "`dirname "${SCRIPT_PATH}"`" > /dev/null
SCRIPT_PATH="`pwd`";
cd $CURRENT_PATH
# Run Node-RED
/usr/bin/env node $OPTIONS $SCRIPT_PATH/../red.js $ARGS

BIN
editor/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 308 B

After

Width:  |  Height:  |  Size: 308 B

View File

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 603 B

View File

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 393 B

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 609 B

After

Width:  |  Height:  |  Size: 609 B

View File

Before

Width:  |  Height:  |  Size: 575 B

After

Width:  |  Height:  |  Size: 575 B

View File

Before

Width:  |  Height:  |  Size: 601 B

After

Width:  |  Height:  |  Size: 601 B

View File

Before

Width:  |  Height:  |  Size: 459 B

After

Width:  |  Height:  |  Size: 459 B

View File

Before

Width:  |  Height:  |  Size: 218 B

After

Width:  |  Height:  |  Size: 218 B

View File

Before

Width:  |  Height:  |  Size: 324 B

After

Width:  |  Height:  |  Size: 324 B

View File

Before

Width:  |  Height:  |  Size: 378 B

After

Width:  |  Height:  |  Size: 378 B

View File

Before

Width:  |  Height:  |  Size: 255 B

After

Width:  |  Height:  |  Size: 255 B

View File

Before

Width:  |  Height:  |  Size: 457 B

After

Width:  |  Height:  |  Size: 457 B

View File

Before

Width:  |  Height:  |  Size: 502 B

After

Width:  |  Height:  |  Size: 502 B

View File

Before

Width:  |  Height:  |  Size: 449 B

After

Width:  |  Height:  |  Size: 449 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 639 B

After

Width:  |  Height:  |  Size: 639 B

View File

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 414 B

BIN
editor/icons/mouse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

View File

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 386 B

View File

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 386 B

View File

Before

Width:  |  Height:  |  Size: 360 B

After

Width:  |  Height:  |  Size: 360 B

View File

Before

Width:  |  Height:  |  Size: 736 B

After

Width:  |  Height:  |  Size: 736 B

View File

Before

Width:  |  Height:  |  Size: 482 B

After

Width:  |  Height:  |  Size: 482 B

View File

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 273 B

BIN
editor/icons/subflow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

View File

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 592 B

View File

Before

Width:  |  Height:  |  Size: 509 B

After

Width:  |  Height:  |  Size: 509 B

View File

Before

Width:  |  Height:  |  Size: 488 B

After

Width:  |  Height:  |  Size: 488 B

View File

Before

Width:  |  Height:  |  Size: 628 B

After

Width:  |  Height:  |  Size: 628 B

View File

Before

Width:  |  Height:  |  Size: 258 B

After

Width:  |  Height:  |  Size: 258 B

View File

Before

Width:  |  Height:  |  Size: 404 B

After

Width:  |  Height:  |  Size: 404 B

View File

Before

Width:  |  Height:  |  Size: 591 B

After

Width:  |  Height:  |  Size: 591 B

View File

Before

Width:  |  Height:  |  Size: 707 B

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

BIN
editor/images/grip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="480" width="480" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 480.00002 479.99999">
<title>Node-RED Icon</title>
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title>Node-RED Icon</dc:title>
<cc:license rdf:resource="http://creativecommons.org/licenses/by/3.0/"/>
<dc:creator>
<cc:Agent>
<dc:title>Nick O&apos;Leary</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by/3.0/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
</cc:License>
</rdf:RDF>
</metadata>
<g transform="translate(0 -572.36)">
<rect style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" ry="56" height="448" width="448" y="588.36" x="16" fill="#8f0000"/>
<g transform="matrix(8.545 0 0 8.545 -786.19 -1949.8)">
<path style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m104.41 321.21c0.0138-2.3846-1.905-4.2806-4.2896-4.2806h-6.243v2.9257h6.243c0.80513 0 1.4808 0.58383 1.4808 1.389v4.2422c0 0.80513-0.67566 1.5075-1.4808 1.5075h-6.243v2.8086h6.243c2.3846 0 4.2895-1.9315 4.2895-4.3162l-0.00005-1.9812c9.8659 0.14125 12.737 2.7065 15.877 5.4519 3.0241 2.6446 6.4153 5.4869 15.252 5.557l0.00046 0.97238c0.001 2.3846 1.9543 4.3803 4.3389 4.3803h6.4273v-3.0427h-6.4273c-0.80514 0-1.4135-0.53255-1.4135-1.3377v-4.2422c0-0.80513 0.60835-1.4418 1.4135-1.4418h6.4273v-2.8086h-6.4273c-2.3846 0-4.3379 1.8658-4.3389 4.2504l-0.00045 1.005c-8.351-0.0276-10.723-2.3434-13.76-4.9992-2.5914-2.2662-5.6368-4.7578-12.346-5.6642 0.0583-0.0501 0.11211-0.0987 0.16838-0.15027 1.2918-1.1846 1.9884-2.6158 2.6699-3.8516 0.68148-1.2357 1.3227-2.267 2.373-2.9879 0.85207-0.58483 2.0639-1.0208 3.926-1.1017l0.00018 0.99192c0.00043 2.3846 1.9236 4.4325 4.3083 4.4325h17.242c2.3846 0 4.3127-2.0479 4.3127-4.4325v-4.2422c0-2.3846-1.9281-4.3153-4.3127-4.3153h-17.242c-2.3846 0-4.3095 1.9306-4.3083 4.3153l0.00051 0.98395c-2.2474 0.0903-3.9508 0.6357-5.2079 1.4985-1.5245 1.0464-2.3662 2.4764-3.0762 3.7637-0.70992 1.2873-1.3108 2.4408-2.2188 3.2734-0.79034 0.72475-1.8834 1.2844-3.658 1.493zm18.468-12.356h17.242c0.80514 0 1.387 0.58455 1.387 1.3897v4.2422c0 0.80514-0.5819 1.3898-1.387 1.3898h-17.242c-0.80514 0-1.4994-0.58462-1.4994-1.3898v-4.2422c0-0.80513 0.69431-1.3897 1.4994-1.3897z" fill="#fff"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1019 B

After

Width:  |  Height:  |  Size: 1019 B

View File

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2014 IBM Corp.
* Copyright 2014, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,31 +13,59 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.comms = (function() {
var errornotification = null;
var clearErrorTimer = null;
var subscriptions = {};
var ws;
var pendingAuth = false;
var reconnectAttempts = 0;
function connectWS() {
var path = location.hostname+":"+location.port+document.location.pathname;
var path = location.hostname;
var port = location.port;
if (port.length !== 0) {
path = path+":"+port;
}
path = path+document.location.pathname;
path = path+(path.slice(-1) == "/"?"":"/")+"comms";
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path;
ws = new WebSocket(path);
ws.onopen = function() {
if (errornotification) {
errornotification.close();
errornotification = null;
}
var auth_tokens = RED.settings.get("auth-tokens");
pendingAuth = (auth_tokens!=null);
function completeConnection() {
for (var t in subscriptions) {
if (subscriptions.hasOwnProperty(t)) {
ws.send(JSON.stringify({subscribe:t}));
}
}
}
ws = new WebSocket(path);
ws.onopen = function() {
reconnectAttempts = 0;
if (errornotification) {
clearErrorTimer = setTimeout(function() {
errornotification.close();
errornotification = null;
},1000);
}
if (pendingAuth) {
ws.send(JSON.stringify({auth:auth_tokens.access_token}));
} else {
completeConnection();
}
}
ws.onmessage = function(event) {
var msg = JSON.parse(event.data);
if (msg.topic) {
if (pendingAuth && msg.auth == "ok") {
pendingAuth = false;
completeConnection();
} else if (msg.topic) {
for (var t in subscriptions) {
if (subscriptions.hasOwnProperty(t)) {
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
@@ -54,13 +82,17 @@ RED.comms = (function() {
}
};
ws.onclose = function() {
if (errornotification == null) {
errornotification = RED.notify("<b>Error</b>: Lost connection to server","error",true);
if (reconnectAttempts > 5 && errornotification == null) {
errornotification = RED.notify(RED._("notification.error",{message:RED._("notification.errors.lostConnection")}),"error",true);
} else if (clearErrorTimer) {
clearTimeout(clearErrorTimer);
clearErrorTimer = null;
}
reconnectAttempts++;
setTimeout(connectWS,1000);
}
}
function subscribe(topic,callback) {
if (subscriptions[topic] == null) {
subscriptions[topic] = [];
@@ -70,21 +102,21 @@ RED.comms = (function() {
ws.send(JSON.stringify({subscribe:topic}));
}
}
function unsubscribe(topic,callback) {
if (subscriptions.topic) {
for (var i=0;i<subscriptions.topic.length;i++) {
if (subscriptions.topic[i] === callback) {
subscriptions.topic.splice(i,1);
if (subscriptions[topic]) {
for (var i=0;i<subscriptions[topic].length;i++) {
if (subscriptions[topic][i] === callback) {
subscriptions[topic].splice(i,1);
break;
}
}
if (subscriptions.topic.length === 0) {
delete subscriptions.topic;
if (subscriptions[topic].length === 0) {
delete subscriptions[topic];
}
}
}
return {
connect: connectWS,
subscribe: subscribe,

48
editor/js/events.js Normal file
View File

@@ -0,0 +1,48 @@
/**
* Copyright 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.events = (function() {
var handlers = {};
function on(evt,func) {
handlers[evt] = handlers[evt]||[];
handlers[evt].push(func);
}
function off(evt,func) {
var handler = handlers[evt];
if (handler) {
for (var i=0;i<handler.length;i++) {
if (handler[i] === func) {
handler.splice(i,1);
return;
}
}
}
}
function emit(evt,arg) {
if (handlers[evt]) {
for (var i=0;i<handlers[evt].length;i++) {
handlers[evt][i](arg);
}
}
}
return {
on: on,
off: off,
emit: emit
}
})();

272
editor/js/history.js Normal file
View File

@@ -0,0 +1,272 @@
/**
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.history = (function() {
var undo_history = [];
return {
//TODO: this function is a placeholder until there is a 'save' event that can be listened to
markAllDirty: function() {
for (var i=0;i<undo_history.length;i++) {
undo_history[i].dirty = true;
}
},
depth: function() {
return undo_history.length;
},
push: function(ev) {
undo_history.push(ev);
},
pop: function() {
var ev = undo_history.pop();
var i;
var node;
var subflow;
var modifiedTabs = {};
if (ev) {
if (ev.t == 'add') {
if (ev.nodes) {
for (i=0;i<ev.nodes.length;i++) {
node = RED.nodes.node(ev.nodes[i]);
if (node.z) {
modifiedTabs[node.z] = true;
}
RED.nodes.remove(ev.nodes[i]);
}
}
if (ev.links) {
for (i=0;i<ev.links.length;i++) {
RED.nodes.removeLink(ev.links[i]);
}
}
if (ev.workspaces) {
for (i=0;i<ev.workspaces.length;i++) {
RED.nodes.removeWorkspace(ev.workspaces[i].id);
RED.workspaces.remove(ev.workspaces[i]);
}
}
if (ev.subflows) {
for (i=0;i<ev.subflows.length;i++) {
RED.nodes.removeSubflow(ev.subflows[i]);
RED.workspaces.remove(ev.subflows[i]);
}
}
if (ev.subflow) {
if (ev.subflow.instances) {
ev.subflow.instances.forEach(function(n) {
var node = RED.nodes.node(n.id);
if (node) {
node.changed = n.changed;
node.dirty = true;
}
});
}
if (ev.subflow.hasOwnProperty('changed')) {
subflow = RED.nodes.subflow(ev.subflow.id);
if (subflow) {
subflow.changed = ev.subflow.changed;
}
}
}
} else if (ev.t == "delete") {
if (ev.workspaces) {
for (i=0;i<ev.workspaces.length;i++) {
RED.nodes.addWorkspace(ev.workspaces[i]);
RED.workspaces.add(ev.workspaces[i]);
}
}
if (ev.subflow && ev.subflow.subflow) {
RED.nodes.addSubflow(ev.subflow.subflow);
}
if (ev.subflowInputs && ev.subflowInputs.length > 0) {
subflow = RED.nodes.subflow(ev.subflowInputs[0].z);
subflow.in.push(ev.subflowInputs[0]);
subflow.in[0].dirty = true;
}
if (ev.subflowOutputs && ev.subflowOutputs.length > 0) {
subflow = RED.nodes.subflow(ev.subflowOutputs[0].z);
ev.subflowOutputs.sort(function(a,b) { return a.i-b.i});
for (i=0;i<ev.subflowOutputs.length;i++) {
var output = ev.subflowOutputs[i];
subflow.out.splice(output.i,0,output);
for (var j=output.i+1;j<subflow.out.length;j++) {
subflow.out[j].i++;
subflow.out[j].dirty = true;
}
RED.nodes.eachLink(function(l) {
if (l.source.type == "subflow:"+subflow.id) {
if (l.sourcePort >= output.i) {
l.sourcePort++;
}
}
});
}
}
if (ev.subflow && ev.subflow.hasOwnProperty('instances')) {
ev.subflow.instances.forEach(function(n) {
var node = RED.nodes.node(n.id);
if (node) {
node.changed = n.changed;
node.dirty = true;
}
});
}
if (subflow) {
RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) {
n.inputs = subflow.in.length;
n.outputs = subflow.out.length;
while (n.outputs > n.ports.length) {
n.ports.push(n.ports.length);
}
n.resize = true;
n.dirty = true;
});
}
if (ev.nodes) {
for (i=0;i<ev.nodes.length;i++) {
RED.nodes.add(ev.nodes[i]);
modifiedTabs[ev.nodes[i].z] = true;
}
}
if (ev.links) {
for (i=0;i<ev.links.length;i++) {
RED.nodes.addLink(ev.links[i]);
}
}
if (ev.changes) {
for (i in ev.changes) {
if (ev.changes.hasOwnProperty(i)) {
node = RED.nodes.node(i);
if (node) {
for (var d in ev.changes[i]) {
if (ev.changes[i].hasOwnProperty(d)) {
node[d] = ev.changes[i][d];
}
}
node.dirty = true;
}
}
}
}
} else if (ev.t == "move") {
for (i=0;i<ev.nodes.length;i++) {
var n = ev.nodes[i];
n.n.x = n.ox;
n.n.y = n.oy;
n.n.dirty = true;
}
} else if (ev.t == "edit") {
for (i in ev.changes) {
if (ev.changes.hasOwnProperty(i)) {
if (ev.node._def.defaults[i].type) {
// This is a config node property
var currentConfigNode = RED.nodes.node(ev.node[i]);
if (currentConfigNode) {
currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1);
}
var newConfigNode = RED.nodes.node(ev.changes[i]);
if (newConfigNode) {
newConfigNode.users.push(ev.node);
}
}
ev.node[i] = ev.changes[i];
}
}
if (ev.subflow) {
if (ev.subflow.hasOwnProperty('inputCount')) {
if (ev.node.in.length > ev.subflow.inputCount) {
ev.node.in.splice(ev.subflow.inputCount);
} else if (ev.subflow.inputs.length > 0) {
ev.node.in = ev.node.in.concat(ev.subflow.inputs);
}
}
if (ev.subflow.hasOwnProperty('outputCount')) {
if (ev.node.out.length > ev.subflow.outputCount) {
ev.node.out.splice(ev.subflow.outputCount);
} else if (ev.subflow.outputs.length > 0) {
ev.node.out = ev.node.out.concat(ev.subflow.outputs);
}
}
if (ev.subflow.hasOwnProperty('instances')) {
ev.subflow.instances.forEach(function(n) {
var node = RED.nodes.node(n.id);
if (node) {
node.changed = n.changed;
node.dirty = true;
}
});
}
RED.nodes.filterNodes({type:"subflow:"+ev.node.id}).forEach(function(n) {
n.inputs = ev.node.in.length;
n.outputs = ev.node.out.length;
RED.editor.updateNodeProperties(n);
});
if (ev.node.type === 'subflow') {
$("#menu-item-workspace-menu-"+ev.node.id.replace(".","-")).text(ev.node.name);
}
} else {
RED.editor.updateNodeProperties(ev.node);
RED.editor.validateNode(ev.node);
}
if (ev.links) {
for (i=0;i<ev.links.length;i++) {
RED.nodes.addLink(ev.links[i]);
}
}
ev.node.dirty = true;
ev.node.changed = ev.changed;
} else if (ev.t == "createSubflow") {
if (ev.nodes) {
RED.nodes.filterNodes({z:ev.subflow.subflow.id}).forEach(function(n) {
n.z = ev.activeWorkspace;
n.dirty = true;
});
for (i=0;i<ev.nodes.length;i++) {
RED.nodes.remove(ev.nodes[i]);
}
}
if (ev.links) {
for (i=0;i<ev.links.length;i++) {
RED.nodes.removeLink(ev.links[i]);
}
}
RED.nodes.removeSubflow(ev.subflow.subflow);
RED.workspaces.remove(ev.subflow.subflow);
if (ev.removedLinks) {
for (i=0;i<ev.removedLinks.length;i++) {
RED.nodes.addLink(ev.removedLinks[i]);
}
}
}
Object.keys(modifiedTabs).forEach(function(id) {
var subflow = RED.nodes.subflow(id);
if (subflow) {
RED.editor.validateNode(subflow);
}
});
RED.nodes.dirty(ev.dirty);
RED.view.redraw(true);
RED.palette.refresh();
RED.workspaces.refresh();
}
}
}
})();

43
editor/js/i18n.js Normal file
View File

@@ -0,0 +1,43 @@
/**
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.i18n = (function() {
return {
init: function(done) {
i18n.init({
resGetPath: 'locales/__ns__',
dynamicLoad: false,
load:'current',
ns: {
namespaces: ["editor","node-red"],
defaultNs: "editor"
},
fallbackLng: ['en-US'],
useCookie: false
},function() {
done();
});
RED["_"] = function() {
return i18n.t.apply(null,arguments);
}
},
loadCatalog: function(namespace,done) {
i18n.loadNamespace(namespace,done);
}
}
})();

232
editor/js/main.js Normal file
View File

@@ -0,0 +1,232 @@
/**
* Copyright 2013, 2015 IBM Corp.
*
* 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.
**/
var RED = (function() {
function loadNodeList() {
$.ajax({
headers: {
"Accept":"application/json"
},
cache: false,
url: 'nodes',
success: function(data) {
RED.nodes.setNodeList(data);
var nsCount = 0;
for(var i=0;i<data.length;i++) {
var ns = data[i];
if (ns.module != "node-red") {
nsCount++;
RED.i18n.loadCatalog(ns.id, function() {
nsCount--;
if (nsCount === 0) {
loadNodes();
}
});
}
}
if (nsCount === 0) {
loadNodes();
}
}
});
}
function loadNodes() {
$.ajax({
headers: {
"Accept":"text/html"
},
cache: false,
url: 'nodes',
success: function(data) {
$("body").append(data);
$("body").i18n();
$(".palette-spinner").hide();
$(".palette-scroll").show();
$("#palette-search").show();
loadFlows();
}
});
}
function loadFlows() {
$.ajax({
headers: {
"Accept":"application/json"
},
cache: false,
url: 'flows',
success: function(nodes) {
RED.nodes.import(nodes);
RED.nodes.dirty(false);
RED.view.redraw(true);
RED.comms.subscribe("status/#",function(topic,msg) {
var parts = topic.split("/");
var node = RED.nodes.node(parts[1]);
if (node) {
if (msg.text) {
msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()});
}
node.status = msg;
if (statusEnabled) {
node.dirty = true;
RED.view.redraw();
}
}
});
RED.comms.subscribe("node/#",function(topic,msg) {
var i,m;
var typeList;
var info;
if (topic == "node/added") {
var addedTypes = [];
for (i=0;i<msg.length;i++) {
m = msg[i];
var id = m.id;
RED.nodes.addNodeSet(m);
addedTypes = addedTypes.concat(m.types);
$.get('nodes/'+id, function(data) {
$("body").append(data);
});
}
if (addedTypes.length) {
typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>";
RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
}
} else if (topic == "node/removed") {
for (i=0;i<msg.length;i++) {
m = msg[i];
info = RED.nodes.removeNodeSet(m.id);
if (info.added) {
typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>";
RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success");
}
}
} else if (topic == "node/enabled") {
if (msg.types) {
info = RED.nodes.getNodeSet(msg.id);
if (info.added) {
RED.nodes.enableNodeSet(msg.id);
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
} else {
$.get('nodes/'+msg.id, function(data) {
$("body").append(data);
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
});
}
}
} else if (topic == "node/disabled") {
if (msg.types) {
RED.nodes.disableNodeSet(msg.id);
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
RED.notify(RED._("palette.event.nodeDisabled", {count:msg.types.length})+typeList,"success");
}
}
});
}
});
}
var statusEnabled = false;
function toggleStatus(state) {
statusEnabled = state;
RED.view.status(statusEnabled);
}
function loadEditor() {
RED.menu.init({id:"btn-sidemenu",
options: [
{id:"menu-item-sidebar-menu",label:RED._("menu.label.sidebar.sidebar"),options:[
{id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:RED.sidebar.toggleSidebar, selected: true},
null
]},
{id:"menu-item-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:toggleStatus, selected: true},
null,
{id:"menu-item-import",label:RED._("menu.label.import"),options:[
{id:"menu-item-import-clipboard",label:RED._("menu.label.clipboard"),onselect:RED.clipboard.import},
{id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]}
]},
{id:"menu-item-export",label:RED._("menu.label.export"),disabled:true,options:[
{id:"menu-item-export-clipboard",label:RED._("menu.label.clipboard"),disabled:true,onselect:RED.clipboard.export},
{id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:RED.library.export}
]},
null,
{id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [
{id:"menu-item-subflow-create",label:RED._("menu.label.createSubflow"),onselect:RED.subflow.createSubflow},
{id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:RED.subflow.convertToSubflow},
]},
null,
{id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[
{id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:RED.workspaces.add},
{id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:RED.workspaces.edit},
{id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:RED.workspaces.remove},
null
]},
null,
{id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:RED.keyboard.showHelp},
{id:"menu-item-help",
label: RED.settings.theme("menu.menu-item-help.label","Node-RED Website"),
href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")
}
]
});
RED.user.init();
RED.library.init();
RED.palette.init();
RED.sidebar.init();
RED.subflow.init();
RED.workspaces.init();
RED.clipboard.init();
RED.view.init();
RED.editor.init();
RED.deploy.init(RED.settings.theme("deployButton",null));
RED.keyboard.add(/* ? */ 191,{shift:true},function(){RED.keyboard.showHelp();d3.event.preventDefault();});
RED.comms.connect();
$("#main-container").show();
$(".header-toolbar").show();
loadNodeList();
}
$(function() {
if ((window.location.hostname !== "localhost") && (window.location.hostname !== "127.0.0.1")) {
document.title = document.title+" : "+window.location.hostname;
}
ace.require("ace/ext/language_tools");
RED.i18n.init(function() {
RED.settings.init(loadEditor);
})
});
return {
};
})();

1027
editor/js/nodes.js Normal file

File diff suppressed because it is too large Load Diff

148
editor/js/settings.js Normal file
View File

@@ -0,0 +1,148 @@
/**
* Copyright 2014 IBM, Antoine Aflalo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.settings = (function () {
var loadedSettings = {};
var hasLocalStorage = function () {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
};
var set = function (key, value) {
if (!hasLocalStorage()) {
return;
}
localStorage.setItem(key, JSON.stringify(value));
};
/**
* If the key is not set in the localStorage it returns <i>undefined</i>
* Else return the JSON parsed value
* @param key
* @returns {*}
*/
var get = function (key) {
if (!hasLocalStorage()) {
return undefined;
}
return JSON.parse(localStorage.getItem(key));
};
var remove = function (key) {
if (!hasLocalStorage()) {
return;
}
localStorage.removeItem(key);
};
var setProperties = function(data) {
for (var prop in loadedSettings) {
if (loadedSettings.hasOwnProperty(prop) && RED.settings.hasOwnProperty(prop)) {
delete RED.settings[prop];
}
}
for (prop in data) {
if (data.hasOwnProperty(prop)) {
RED.settings[prop] = data[prop];
}
}
loadedSettings = data;
};
var init = function (done) {
var accessTokenMatch = /[?&]access_token=(.*?)(?:$|&)/.exec(window.location.search);
if (accessTokenMatch) {
var accessToken = accessTokenMatch[1];
RED.settings.set("auth-tokens",{access_token: accessToken});
window.location.search = "";
}
$.ajaxSetup({
beforeSend: function(jqXHR,settings) {
// Only attach auth header for requests to relative paths
if (!/^\s*(https?:|\/|\.)/.test(settings.url)) {
var auth_tokens = RED.settings.get("auth-tokens");
if (auth_tokens) {
jqXHR.setRequestHeader("Authorization","Bearer "+auth_tokens.access_token);
}
}
}
});
load(done);
}
var load = function(done) {
$.ajax({
headers: {
"Accept": "application/json"
},
dataType: "json",
cache: false,
url: 'settings',
success: function (data) {
setProperties(data);
if (RED.settings.user && RED.settings.user.anonymous) {
RED.settings.remove("auth-tokens");
}
console.log("Node-RED: " + data.version);
done();
},
error: function(jqXHR,textStatus,errorThrown) {
if (jqXHR.status === 401) {
if (/[?&]access_token=(.*?)(?:$|&)/.test(window.location.search)) {
window.location.search = "";
}
RED.user.login(function() { load(done); });
} else {
console.log("Unexpected error:",jqXHR.status,textStatus);
}
}
});
};
function theme(property,defaultValue) {
if (!RED.settings.editorTheme) {
return defaultValue;
}
var parts = property.split(".");
var v = RED.settings.editorTheme;
try {
for (var i=0;i<parts.length;i++) {
v = v[parts[i]];
}
return v;
} catch(err) {
return defaultValue;
}
}
return {
init: init,
load: load,
set: set,
get: get,
remove: remove,
theme: theme
}
})
();

192
editor/js/ui/clipboard.js Normal file
View File

@@ -0,0 +1,192 @@
/**
* Copyright 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.clipboard = (function() {
var dialog;
var dialogContainer;
var exportNodesDialog;
var importNodesDialog;
function setupDialogs(){
dialog = $('<div id="clipboard-dialog" class="hide"><form class="dialog-form form-horizontal"></form></div>')
.appendTo("body")
.dialog({
modal: true,
autoOpen: false,
width: 500,
resizable: false,
buttons: [
{
id: "clipboard-dialog-ok",
text: RED._("common.label.ok"),
click: function() {
if (/Import/.test(dialog.dialog("option","title"))) {
RED.view.importNodes($("#clipboard-import").val());
}
$( this ).dialog( "close" );
}
},
{
id: "clipboard-dialog-cancel",
text: RED._("common.label.cancel"),
click: function() {
$( this ).dialog( "close" );
}
},
{
id: "clipboard-dialog-close",
text: RED._("common.label.close"),
click: function() {
$( this ).dialog( "close" );
}
}
],
open: function(e) {
$(this).parent().find(".ui-dialog-titlebar-close").hide();
RED.keyboard.disable();
},
close: function(e) {
RED.keyboard.enable();
}
});
dialogContainer = dialog.children(".dialog-form");
exportNodesDialog = '<div class="form-row">'+
'<label for="node-input-export" style="display: block; width:100%;"><i class="fa fa-clipboard"></i> '+RED._("clipboard.nodes")+'</label>'+
'<textarea readonly style="resize: none; width: 100%; border-radius: 0px;font-family: monospace; font-size: 12px; background:#eee; padding-left: 0.5em; box-sizing:border-box;" id="clipboard-export" rows="5"></textarea>'+
'</div>'+
'<div class="form-tips">'+
RED._("clipboard.selectNodes")+
'</div>';
importNodesDialog = '<div class="form-row">'+
'<textarea style="resize: none; width: 100%; border-radius: 0px;font-family: monospace; font-size: 12px; background:#eee; padding-left: 0.5em; box-sizing:border-box;" id="clipboard-import" rows="5" placeholder="'+
RED._("clipboard.pasteNodes")+
'"></textarea>'+
'</div>';
}
function validateImport() {
var importInput = $("#clipboard-import");
var v = importInput.val();
try {
JSON.parse(v);
importInput.removeClass("input-error");
$("#clipboard-dialog-ok").button("enable");
} catch(err) {
if (v !== "") {
importInput.addClass("input-error");
}
$("#clipboard-dialog-ok").button("disable");
}
}
function importNodes() {
dialogContainer.empty();
dialogContainer.append($(importNodesDialog));
$("#clipboard-dialog-ok").show();
$("#clipboard-dialog-cancel").show();
$("#clipboard-dialog-close").hide();
$("#clipboard-dialog-ok").button("disable");
$("#clipboard-import").keyup(validateImport);
$("#clipboard-import").on('paste',function() { setTimeout(validateImport,10)});
dialog.dialog("option","title",RED._("clipboard.importNodes")).dialog("open");
}
function exportNodes() {
dialogContainer.empty();
dialogContainer.append($(exportNodesDialog));
$("#clipboard-dialog-ok").hide();
$("#clipboard-dialog-cancel").hide();
$("#clipboard-dialog-close").show();
var selection = RED.view.selection();
if (selection.nodes) {
var nns = RED.nodes.createExportableNodeSet(selection.nodes);
$("#clipboard-export")
.val(JSON.stringify(nns))
.focus(function() {
var textarea = $(this);
textarea.select();
textarea.mouseup(function() {
textarea.unbind("mouseup");
return false;
})
});
dialog.dialog("option","title",RED._("clipboard.exportNodes")).dialog( "open" );
}
}
function hideDropTarget() {
$("#dropTarget").hide();
RED.keyboard.remove(/* ESCAPE */ 27);
}
return {
init: function() {
setupDialogs();
RED.events.on("view:selection-changed",function(selection) {
if (!selection.nodes) {
RED.menu.setDisabled("menu-item-export",true);
RED.menu.setDisabled("menu-item-export-clipboard",true);
RED.menu.setDisabled("menu-item-export-library",true);
} else {
RED.menu.setDisabled("menu-item-export",false);
RED.menu.setDisabled("menu-item-export-clipboard",false);
RED.menu.setDisabled("menu-item-export-library",false);
}
});
RED.keyboard.add(/* e */ 69,{ctrl:true},function(){exportNodes();d3.event.preventDefault();});
RED.keyboard.add(/* i */ 73,{ctrl:true},function(){importNodes();d3.event.preventDefault();});
$('#chart').on("dragenter",function(event) {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
$("#dropTarget").css({display:'table'});
RED.keyboard.add(/* ESCAPE */ 27,hideDropTarget);
}
});
$('#dropTarget').on("dragover",function(event) {
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
event.preventDefault();
}
})
.on("dragleave",function(event) {
hideDropTarget();
})
.on("drop",function(event) {
var data = event.originalEvent.dataTransfer.getData("text/plain");
hideDropTarget();
RED.view.importNodes(data);
event.preventDefault();
});
},
import: importNodes,
export: exportNodes
}
})();

280
editor/js/ui/deploy.js Normal file
View File

@@ -0,0 +1,280 @@
/**
* Copyright 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.deploy = (function() {
var deploymentTypes = {
"full":{img:"red/images/deploy-full-o.png"},
"nodes":{img:"red/images/deploy-nodes-o.png"},
"flows":{img:"red/images/deploy-flows-o.png"}
}
var ignoreDeployWarnings = {
unknown: false,
unusedConfig: false,
invalid: false
}
var deploymentType = "full";
function changeDeploymentType(type) {
deploymentType = type;
$("#btn-deploy img").attr("src",deploymentTypes[type].img);
}
/**
* options:
* type: "default" - Button with drop-down options - no further customisation available
* type: "simple" - Button without dropdown. Customisations:
* label: the text to display - default: "Deploy"
* icon : the icon to use. Null removes the icon. default: "red/images/deploy-full-o.png"
*/
function init(options) {
options = options || {};
var type = options.type || "default";
if (type == "default") {
$('<li><span class="deploy-button-group button-group">'+
'<a id="btn-deploy" class="deploy-button disabled" href="#"><img id="btn-deploy-icon" src="red/images/deploy-full-o.png"> <span>'+RED._("deploy.deploy")+'</span></a>'+
'<a id="btn-deploy-options" data-toggle="dropdown" class="deploy-button" href="#"><i class="fa fa-caret-down"></i></a>'+
'</span></li>').prependTo(".header-toolbar");
RED.menu.init({id:"btn-deploy-options",
options: [
{id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.png",label:RED._("deploy.full"),sublabel:RED._("deploy.fullDesc"),selected: true, onselect:function(s) { if(s){changeDeploymentType("full")}}},
{id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.png",label:RED._("deploy.modifiedFlows"),sublabel:RED._("deploy.modifiedFlowsDesc"), onselect:function(s) {if(s){changeDeploymentType("flows")}}},
{id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.png",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}}
]
});
} else if (type == "simple") {
var label = options.label || RED._("deploy.deploy");
var icon = 'red/images/deploy-full-o.png';
if (options.hasOwnProperty('icon')) {
icon = options.icon;
}
$('<li><span class="deploy-button-group button-group">'+
'<a id="btn-deploy" class="deploy-button disabled" href="#">'+
(icon?'<img id="btn-deploy-icon" src="'+icon+'"> ':'')+
'<span>'+label+'</span></a>'+
'</span></li>').prependTo(".header-toolbar");
}
$('#btn-deploy').click(function() { save(); });
$( "#node-dialog-confirm-deploy" ).dialog({
title: "Confirm deploy",
modal: true,
autoOpen: false,
width: 550,
height: "auto",
buttons: [
{
text: RED._("deploy.confirm.button.confirm"),
click: function() {
var ignoreChecked = $( "#node-dialog-confirm-deploy-hide" ).prop("checked");
if (ignoreChecked) {
ignoreDeployWarnings[$( "#node-dialog-confirm-deploy-type" ).val()] = true;
}
save(true);
$( this ).dialog( "close" );
}
},
{
text: RED._("deploy.confirm.button.cancel"),
click: function() {
$( this ).dialog( "close" );
}
}
],
create: function() {
$("#node-dialog-confirm-deploy").parent().find("div.ui-dialog-buttonpane")
.prepend('<div style="height:0; vertical-align: middle; display:inline-block; margin-top: 13px; float:left;">'+
'<input style="vertical-align:top;" type="checkbox" id="node-dialog-confirm-deploy-hide">'+
'<label style="display:inline;" for="node-dialog-confirm-deploy-hide"> do not warn about this again</label>'+
'<input type="hidden" id="node-dialog-confirm-deploy-type">'+
'</div>');
}
});
RED.events.on('nodes:change',function(state) {
if (state.dirty) {
window.onbeforeunload = function() {
return RED._("deploy.confirm.undeployedChanges");
}
$("#btn-deploy").removeClass("disabled");
} else {
window.onbeforeunload = null;
$("#btn-deploy").addClass("disabled");
}
});
}
function getNodeInfo(node) {
var tabLabel = "";
if (node.z) {
var tab = RED.nodes.workspace(node.z);
if (!tab) {
tab = RED.nodes.subflow(node.z);
tabLabel = tab.name;
} else {
tabLabel = tab.label;
}
}
var label = "";
if (typeof node._def.label == "function") {
label = node._def.label.call(node);
} else {
label = node._def.label;
}
label = label || node.id;
return {tab:tabLabel,type:node.type,label:label};
}
function sortNodeInfo(A,B) {
if (A.tab < B.tab) { return -1;}
if (A.tab > B.tab) { return 1;}
if (A.type < B.type) { return -1;}
if (A.type > B.type) { return 1;}
if (A.name < B.name) { return -1;}
if (A.name > B.name) { return 1;}
return 0;
}
function save(force) {
if (RED.nodes.dirty()) {
//$("#debug-tab-clear").click(); // uncomment this to auto clear debug on deploy
if (!force) {
var hasUnknown = false;
var hasInvalid = false;
var hasUnusedConfig = false;
var unknownNodes = [];
var invalidNodes = [];
RED.nodes.eachNode(function(node) {
hasInvalid = hasInvalid || !node.valid;
if (!node.valid) {
invalidNodes.push(getNodeInfo(node));
}
if (node.type === "unknown") {
if (unknownNodes.indexOf(node.name) == -1) {
unknownNodes.push(node.name);
}
}
});
hasUnknown = unknownNodes.length > 0;
var unusedConfigNodes = [];
RED.nodes.eachConfig(function(node) {
if (node.users.length === 0) {
unusedConfigNodes.push(getNodeInfo(node));
hasUnusedConfig = true;
}
});
$( "#node-dialog-confirm-deploy-config" ).hide();
$( "#node-dialog-confirm-deploy-unknown" ).hide();
$( "#node-dialog-confirm-deploy-unused" ).hide();
var showWarning = false;
if (hasUnknown && !ignoreDeployWarnings.unknown) {
showWarning = true;
$( "#node-dialog-confirm-deploy-type" ).val("unknown");
$( "#node-dialog-confirm-deploy-unknown" ).show();
$( "#node-dialog-confirm-deploy-unknown-list" )
.html("<li>"+unknownNodes.join("</li><li>")+"</li>");
} else if (hasInvalid && !ignoreDeployWarnings.invalid) {
showWarning = true;
$( "#node-dialog-confirm-deploy-type" ).val("invalid");
$( "#node-dialog-confirm-deploy-config" ).show();
invalidNodes.sort(sortNodeInfo);
$( "#node-dialog-confirm-deploy-invalid-list" )
.html("<li>"+invalidNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"}).join("</li><li>")+"</li>");
} else if (hasUnusedConfig && !ignoreDeployWarnings.unusedConfig) {
showWarning = true;
$( "#node-dialog-confirm-deploy-type" ).val("unusedConfig");
$( "#node-dialog-confirm-deploy-unused" ).show();
unusedConfigNodes.sort(sortNodeInfo);
$( "#node-dialog-confirm-deploy-unused-list" )
.html("<li>"+unusedConfigNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"}).join("</li><li>")+"</li>");
}
if (showWarning) {
$( "#node-dialog-confirm-deploy-hide" ).prop("checked",false);
$( "#node-dialog-confirm-deploy" ).dialog( "open" );
return;
}
}
var nns = RED.nodes.createCompleteNodeSet();
$("#btn-deploy-icon").removeClass('fa-download');
$("#btn-deploy-icon").addClass('spinner');
RED.nodes.dirty(false);
$.ajax({
url:"flows",
type: "POST",
data: JSON.stringify(nns),
contentType: "application/json; charset=utf-8",
headers: {
"Node-RED-Deployment-Type":deploymentType
}
}).done(function(data,textStatus,xhr) {
RED.notify(RED._("deploy.successfulDeploy"),"success");
RED.nodes.eachNode(function(node) {
if (node.changed) {
node.dirty = true;
node.changed = false;
}
if(node.credentials) {
delete node.credentials;
}
});
RED.nodes.eachConfig(function (confNode) {
if (confNode.credentials) {
delete confNode.credentials;
}
});
// Once deployed, cannot undo back to a clean state
RED.history.markAllDirty();
RED.view.redraw();
RED.events.emit("deploy");
}).fail(function(xhr,textStatus,err) {
RED.nodes.dirty(true);
if (xhr.responseText) {
RED.notify(RED._("notification.error",{message:xhr.responseText}),"error");
} else {
RED.notify(RED._("notification.error",{message:RED._("deploy.errors.noResponse")}),"error");
}
}).always(function() {
$("#btn-deploy-icon").removeClass('spinner');
$("#btn-deploy-icon").addClass('fa-download');
});
}
}
return {
init: init
}
})();

1212
editor/js/ui/editor.js Normal file

File diff suppressed because it is too large Load Diff

121
editor/js/ui/keyboard.js Normal file
View File

@@ -0,0 +1,121 @@
/**
* Copyright 2013 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.keyboard = (function() {
var active = true;
var handlers = {};
d3.select(window).on("keydown",function() {
if (!active) { return; }
var handler = handlers[d3.event.keyCode];
if (handler && handler.ondown) {
if (!handler.modifiers ||
((!handler.modifiers.shift || d3.event.shiftKey) &&
(!handler.modifiers.ctrl || d3.event.ctrlKey || d3.event.metaKey) &&
(!handler.modifiers.alt || d3.event.altKey) )) {
handler.ondown();
}
}
});
d3.select(window).on("keyup",function() {
if (!active) { return; }
var handler = handlers[d3.event.keyCode];
if (handler && handler.onup) {
if (!handler.modifiers ||
((!handler.modifiers.shift || d3.event.shiftKey) &&
(!handler.modifiers.ctrl || d3.event.ctrlKey || d3.event.metaKey) &&
(!handler.modifiers.alt || d3.event.altKey) )) {
handler.onup();
}
}
});
function addHandler(key,modifiers,ondown,onup) {
var mod = modifiers;
var cbdown = ondown;
var cbup = onup;
if (typeof modifiers == "function") {
mod = {};
cbdown = modifiers;
cbup = ondown;
}
handlers[key] = {modifiers:mod, ondown:cbdown, onup:cbup};
}
function removeHandler(key) {
delete handlers[key];
}
var dialog = null;
function showKeyboardHelp() {
if (!RED.settings.theme("menu.menu-item-keyboard-shortcuts",true)) {
return;
}
if (!dialog) {
dialog = $('<div id="keyboard-help-dialog" class="hide">'+
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
'<table class="keyboard-shortcuts">'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">a</span></td><td>'+RED._("keyboard.selectAll")+'</td></tr>'+
'<tr><td><span class="help-key">Shift</span> + <span class="help-key">Click</span></td><td>'+RED._("keyboard.selectAllConnected")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">Click</span></td><td>'+RED._("keyboard.addRemoveNode")+'</td></tr>'+
'<tr><td><span class="help-key">Delete</span></td><td>'+RED._("keyboard.deleteSelected")+'</td></tr>'+
'<tr><td>&nbsp;</td><td></td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">i</span></td><td>'+RED._("keyboard.importNode")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">e</span></td><td>'+RED._("keyboard.exportNode")+'</td></tr>'+
'</table>'+
'</div>'+
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
'<table class="keyboard-shortcuts">'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">Space</span></td><td>'+RED._("keyboard.toggleSidebar")+'</td></tr>'+
'<tr><td></td><td></td></tr>'+
'<tr><td><span class="help-key">Delete</span></td><td>'+RED._("keyboard.deleteNode")+'</td></tr>'+
'<tr><td></td><td></td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">c</span></td><td>'+RED._("keyboard.copyNode")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">x</span></td><td>'+RED._("keyboard.cutNode")+'</td></tr>'+
'<tr><td><span class="help-key">Ctrl/&#8984;</span> + <span class="help-key">v</span></td><td>'+RED._("keyboard.pasteNode")+'</td></tr>'+
'</table>'+
'</div>'+
'</div>')
.appendTo("body")
.dialog({
modal: true,
autoOpen: false,
width: "800",
title:"Keyboard shortcuts",
resizable: false,
open: function() {
RED.keyboard.disable();
},
close: function() {
RED.keyboard.enable();
}
});
}
dialog.dialog("open");
}
return {
add: addHandler,
remove: removeHandler,
disable: function(){ active = false;},
enable: function(){ active = true; },
showHelp: showKeyboardHelp
}
})();

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2013 IBM Corp.
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
* limitations under the License.
**/
RED.library = (function() {
function loadFlowLibrary() {
$.getJSON("library/flows",function(data) {
//console.log(data);
@@ -25,7 +25,7 @@ RED.library = (function() {
var li;
var a;
var ul = document.createElement("ul");
ul.id = "btn-import-library-submenu";
ul.id = "menu-item-import-library-submenu";
ul.className = "dropdown-menu";
if (data.d) {
for (i in data.d) {
@@ -63,25 +63,35 @@ RED.library = (function() {
};
var menu = buildMenu(data,"");
//TODO: need an api in RED.menu for this
$("#btn-import-library-submenu").replaceWith(menu);
$("#menu-item-import-library-submenu").replaceWith(menu);
});
}
loadFlowLibrary();
function createUI(options) {
var libraryData = {};
var selectedLibraryItem = null;
var libraryEditor = null;
// Orion editor has set/getText
// ACE editor has set/getValue
// normalise to set/getValue
if (options.editor.setText) {
// Orion doesn't like having pos passed in, so proxy the call to drop it
options.editor.setValue = function(text,pos) {
options.editor.setText.call(options.editor,text);
}
}
if (options.editor.getText) {
options.editor.getValue = options.editor.getText;
}
function buildFileListItem(item) {
var li = document.createElement("li");
li.onmouseover = function(e) { $(this).addClass("list-hover"); };
li.onmouseout = function(e) { $(this).removeClass("list-hover"); };
return li;
}
function buildFileList(root,data) {
var ul = document.createElement("ul");
var li;
@@ -94,7 +104,7 @@ RED.library = (function() {
var dirName = v;
return function(e) {
var bcli = $('<li class="active"><span class="divider">/</span> <a href="#">'+dirName+'</a></li>');
$("a",bcli).click(function(e) {
$("a",bcli).click(function(e) {
$(this).parent().nextAll().remove();
$.getJSON("library/"+options.url+root+dirName,function(data) {
$("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data));
@@ -122,7 +132,7 @@ RED.library = (function() {
$(this).addClass("list-selected");
$.get("library/"+options.url+root+item.fn, function(data) {
selectedLibraryItem = item;
libraryEditor.setText(data);
libraryEditor.setValue(data,-1);
});
}
})();
@@ -131,24 +141,24 @@ RED.library = (function() {
}
return ul;
}
$('#node-input-name').addClass('input-append-left').css("width","65%").after(
'<div class="btn-group" style="margin-left: 0px;">'+
'<button id="node-input-'+options.type+'-lookup" class="btn input-append-right" data-toggle="dropdown"><i class="fa fa-book"></i> <i class="fa fa-caret-down"></i></button>'+
$('#node-input-name').css("width","60%").after(
'<div class="btn-group" style="margin-left: 5px;">'+
'<a id="node-input-'+options.type+'-lookup" class="editor-button" data-toggle="dropdown"><i class="fa fa-book"></i> <i class="fa fa-caret-down"></i></a>'+
'<ul class="dropdown-menu pull-right" role="menu">'+
'<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">Open Library...</a></li>'+
'<li><a id="node-input-'+options.type+'-menu-save-library" tabindex="-1" href="#">Save to Library...</a></li>'+
'<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">'+RED._("library.openLibrary")+'</a></li>'+
'<li><a id="node-input-'+options.type+'-menu-save-library" tabindex="-1" href="#">'+RED._("library.saveToLibrary")+'</a></li>'+
'</ul></div>'
);
$('#node-input-'+options.type+'-menu-open-library').click(function(e) {
$("#node-select-library").children().remove();
var bc = $("#node-dialog-library-breadcrumbs");
bc.children().first().nextAll().remove();
libraryEditor.setText('');
libraryEditor.setValue('',-1);
$.getJSON("library/"+options.url,function(data) {
$("#node-select-library").append(buildFileList("/",data));
$("#node-dialog-library-breadcrumbs a").click(function(e) {
@@ -158,10 +168,10 @@ RED.library = (function() {
});
$( "#node-dialog-library-lookup" ).dialog( "open" );
});
e.preventDefault();
});
$('#node-input-'+options.type+'-menu-save-library').click(function(e) {
//var found = false;
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
@@ -207,38 +217,42 @@ RED.library = (function() {
$( "#node-dialog-library-save" ).dialog( "open" );
e.preventDefault();
});
require(["orion/editor/edit"], function(edit) {
libraryEditor = edit({
parent:document.getElementById('node-select-library-text'),
lang:"js",
readonly: true
});
libraryEditor = ace.edit('node-select-library-text');
libraryEditor.setTheme("ace/theme/tomorrow");
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;
$( "#node-dialog-library-lookup" ).dialog({
title: options.type+" library",
title: RED._("library.typeLibrary", {type:options.type}),
modal: true,
autoOpen: false,
width: 800,
height: 450,
buttons: [
{
text: "Ok",
text: RED._("common.label.ok"),
click: function() {
if (selectedLibraryItem) {
for (var i=0;i<options.fields.length;i++) {
var field = options.fields[i];
$("#node-input-"+field).val(selectedLibraryItem[field]);
}
options.editor.setText(libraryEditor.getText());
options.editor.setValue(libraryEditor.getValue(),-1);
}
$( this ).dialog( "close" );
}
},
{
text: "Cancel",
text: RED._("common.label.cancel"),
click: function() {
$( this ).dialog( "close" );
}
@@ -256,16 +270,16 @@ RED.library = (function() {
$(".form-row:last-child",form).children().height(form.height()-60);
}
});
function saveToLibrary(overwrite) {
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
if (name === "") {
name = "Unnamed "+options.type;
name = RED._("library.unnamedType",{type:options.type});
}
var filename = $("#node-dialog-library-save-filename").val().replace(/(^\s*)|(\s*$)/g,"");
var pathname = $("#node-dialog-library-save-folder").val().replace(/(^\s*)|(\s*$)/g,"");
if (filename === "" || !/.+\.js$/.test(filename)) {
RED.notify("Invalid filename","warning");
RED.notify(RED._("library.invalidFilename"),"warning");
return;
}
var fullpath = pathname+(pathname===""?"":"/")+filename;
@@ -290,44 +304,50 @@ RED.library = (function() {
// }
//}
//if (exists) {
// $("#node-dialog-library-save-type").html(options.type);
// $("#node-dialog-library-save-name").html(fullpath);
// $("#node-dialog-library-save-content").html(RED._("library.dialogSaveOverwrite",{libraryType:options.type,libraryName:fullpath}));
// $("#node-dialog-library-save-confirm").dialog( "open" );
// return;
//}
}
var queryArgs = [];
var data = {};
for (var i=0;i<options.fields.length;i++) {
var field = options.fields[i];
if (field == "name") {
queryArgs.push("name="+encodeURIComponent(name));
data.name = name;
} else {
queryArgs.push(encodeURIComponent(field)+"="+encodeURIComponent($("#node-input-"+field).val()));
data[field] = $("#node-input-"+field).val();
}
}
var queryString = queryArgs.join("&");
var text = options.editor.getText();
$.post("library/"+options.url+'/'+fullpath+"?"+queryString,text,function() {
RED.notify("Saved "+options.type,"success");
data.text = options.editor.getValue();
$.ajax({
url:"library/"+options.url+'/'+fullpath,
type: "POST",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8"
}).done(function(data,textStatus,xhr) {
RED.notify(RED._("library.savedType", {type:options.type}),"success");
}).fail(function(xhr,textStatus,err) {
RED.notify(RED._("library.saveFailed",{message:xhr.responseText}),"error");
});
}
$( "#node-dialog-library-save-confirm" ).dialog({
title: "Save to library",
title: RED._("library.saveToLibrary"),
modal: true,
autoOpen: false,
width: 530,
height: 230,
buttons: [
{
text: "Ok",
text: RED._("common.label.ok"),
click: function() {
saveToLibrary(true);
$( this ).dialog( "close" );
}
},
{
text: "Cancel",
text: RED._("common.label.cancel"),
click: function() {
$( this ).dialog( "close" );
}
@@ -335,21 +355,21 @@ RED.library = (function() {
]
});
$( "#node-dialog-library-save" ).dialog({
title: "Save to library",
title: RED._("library.saveToLibrary"),
modal: true,
autoOpen: false,
width: 530,
height: 230,
buttons: [
{
text: "Ok",
text: RED._("common.label.ok"),
click: function() {
saveToLibrary(false);
$( this ).dialog( "close" );
}
},
{
text: "Cancel",
text: RED._("common.label.cancel"),
click: function() {
$( this ).dialog( "close" );
}
@@ -358,11 +378,37 @@ RED.library = (function() {
});
}
function exportFlow() {
//TODO: don't rely on the main dialog
var nns = RED.nodes.createExportableNodeSet(RED.view.selection().nodes);
$("#dialog-form").html($("script[data-template-name='export-library-dialog']").html());
$("#node-input-filename").attr('nodes',JSON.stringify(nns));
$("#dialog").i18n();
$("#dialog").dialog("option","title",RED._("library.exportToLibrary")).dialog( "open" );
}
return {
init: function() {
RED.events.on("view:selection-changed",function(selection) {
if (!selection.nodes) {
RED.menu.setDisabled("menu-item-export",true);
RED.menu.setDisabled("menu-item-export-clipboard",true);
RED.menu.setDisabled("menu-item-export-library",true);
} else {
RED.menu.setDisabled("menu-item-export",false);
RED.menu.setDisabled("menu-item-export-clipboard",false);
RED.menu.setDisabled("menu-item-export-library",false);
}
});
if (RED.settings.theme("menu.menu-item-import-library") !== false) {
loadFlowLibrary();
}
},
create: createUI,
loadFlowLibrary: loadFlowLibrary
loadFlowLibrary: loadFlowLibrary,
export: exportFlow
}
})();

257
editor/js/ui/menu.js Normal file
View File

@@ -0,0 +1,257 @@
/**
* Copyright 2014 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.menu = (function() {
var menuItems = {};
function createMenuItem(opt) {
var item;
if (opt !== null && opt.id) {
var themeSetting = RED.settings.theme("menu."+opt.id);
if (themeSetting === false) {
return null;
}
}
function setInitialState() {
var savedStateActive = isSavedStateActive(opt.id);
if (savedStateActive) {
link.addClass("active");
opt.onselect.call(opt, true);
} else if (savedStateActive === false) {
link.removeClass("active");
opt.onselect.call(opt, false);
} else if (opt.hasOwnProperty("selected")) {
if (opt.selected) {
link.addClass("active");
} else {
link.removeClass("active");
}
opt.onselect.call(opt, opt.selected);
}
}
if (opt === null) {
item = $('<li class="divider"></li>');
} else {
item = $('<li></li>');
if (opt.group) {
item.addClass("menu-group-"+opt.group);
}
var linkContent = '<a '+(opt.id?'id="'+opt.id+'" ':'')+'tabindex="-1" href="#">';
if (opt.toggle) {
linkContent += '<i class="fa fa-square pull-left"></i>';
linkContent += '<i class="fa fa-check-square pull-left"></i>';
}
if (opt.icon !== undefined) {
if (/\.png/.test(opt.icon)) {
linkContent += '<img src="'+opt.icon+'"/> ';
} else {
linkContent += '<i class="'+(opt.icon?opt.icon:'" style="display: inline-block;"')+'"></i> ';
}
}
if (opt.sublabel) {
linkContent += '<span class="menu-label-container"><span class="menu-label">'+opt.label+'</span>'+
'<span class="menu-sublabel">'+opt.sublabel+'</span></span>'
} else {
linkContent += '<span class="menu-label">'+opt.label+'</span>'
}
linkContent += '</a>';
var link = $(linkContent).appendTo(item);
menuItems[opt.id] = opt;
if (opt.onselect) {
link.click(function() {
if ($(this).parent().hasClass("disabled")) {
return;
}
if (opt.toggle) {
var selected = isSelected(opt.id);
if (typeof opt.toggle === "string") {
if (!selected) {
for (var m in menuItems) {
if (menuItems.hasOwnProperty(m)) {
var mi = menuItems[m];
if (mi.id != opt.id && opt.toggle == mi.toggle) {
setSelected(mi.id,false);
}
}
}
setSelected(opt.id,true);
}
} else {
setSelected(opt.id, !selected);
}
} else {
opt.onselect.call(opt);
}
});
setInitialState();
} else if (opt.href) {
link.attr("target","_blank").attr("href",opt.href);
} else if (!opt.options) {
item.addClass("disabled");
link.click(function(event) {
event.preventDefault();
});
}
if (opt.options) {
item.addClass("dropdown-submenu pull-left");
var submenu = $('<ul id="'+opt.id+'-submenu" class="dropdown-menu"></ul>').appendTo(item);
for (var i=0;i<opt.options.length;i++) {
var li = createMenuItem(opt.options[i]);
if (li) {
li.appendTo(submenu);
}
}
}
if (opt.disabled) {
item.addClass("disabled");
}
}
return item;
}
function createMenu(options) {
var button = $("#"+options.id);
//button.click(function(event) {
// $("#"+options.id+"-submenu").show();
// event.preventDefault();
//});
var topMenu = $("<ul/>",{id:options.id+"-submenu", class:"dropdown-menu pull-right"}).insertAfter(button);
var lastAddedSeparator = false;
for (var i=0;i<options.options.length;i++) {
var opt = options.options[i];
if (opt !== null || !lastAddedSeparator) {
var li = createMenuItem(opt);
if (li) {
li.appendTo(topMenu);
lastAddedSeparator = (opt === null);
}
}
}
}
function isSavedStateActive(id) {
return RED.settings.get("menu-" + id);
}
function isSelected(id) {
return $("#" + id).hasClass("active");
}
function setSavedState(id, state) {
RED.settings.set("menu-" + id, state);
}
function setSelected(id,state) {
if (isSelected(id) == state) {
return;
}
var opt = menuItems[id];
if (state) {
$("#"+id).addClass("active");
} else {
$("#"+id).removeClass("active");
}
if (opt && opt.onselect) {
opt.onselect.call(opt,state);
}
setSavedState(id, state);
}
function setDisabled(id,state) {
if (state) {
$("#"+id).parent().addClass("disabled");
} else {
$("#"+id).parent().removeClass("disabled");
}
}
function addItem(id,opt) {
var item = createMenuItem(opt);
if (opt.group) {
var groupItems = $("#"+id+"-submenu").children(".menu-group-"+opt.group);
if (groupItems.length === 0) {
item.appendTo("#"+id+"-submenu");
} else {
for (var i=0;i<groupItems.length;i++) {
var groupItem = groupItems[i];
var label = $(groupItem).find(".menu-label").html();
if (opt.label < label) {
$(groupItem).before(item);
break;
}
}
if (i === groupItems.length) {
item.appendTo("#"+id+"-submenu");
}
}
} else {
item.appendTo("#"+id+"-submenu");
}
}
function removeItem(id) {
$("#"+id).parent().remove();
}
function setAction(id,action) {
var opt = menuItems[id];
if (opt) {
opt.onselect = action;
$("#"+id).click(function() {
if ($(this).parent().hasClass("disabled")) {
return;
}
if (menuItems[id].toggle) {
setSelected(id,!isSelected(id));
} else {
menuItems[id].onselect.call(menuItems[id]);
}
});
}
}
return {
init: createMenu,
setSelected: setSelected,
isSelected: isSelected,
setDisabled: setDisabled,
addItem: addItem,
removeItem: removeItem,
setAction: setAction
//TODO: add an api for replacing a submenu - see library.js:loadFlowLibrary
}
})();

View File

@@ -30,10 +30,10 @@ RED.notify = (function() {
}
var n = document.createElement("div");
n.id="red-notification-"+c;
n.className = "alert";
n.className = "notification";
n.fixed = fixed;
if (type) {
n.className = "alert alert-"+type;
n.className = "notification notification-"+type;
}
n.style.display = "none";
n.innerHTML = msg;
@@ -44,7 +44,7 @@ RED.notify = (function() {
return function() {
currentNotifications.splice(currentNotifications.indexOf(nn),1);
$(nn).slideUp(300, function() {
nn.parentNode.removeChild(nn);
nn.parentNode.removeChild(nn);
});
};
})();
@@ -56,4 +56,3 @@ RED.notify = (function() {
return n;
}
})();

380
editor/js/ui/palette.js Normal file
View File

@@ -0,0 +1,380 @@
/**
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.palette = (function() {
var exclusion = ['config','unknown','deprecated'];
var core = ['subflows', 'input', 'output', 'function', 'social', 'mobile', 'storage', 'analysis', 'advanced'];
var categoryContainers = {};
function createCategoryContainer(category, label){
label = label || category.replace("_", " ");
var catDiv = $('<div id="palette-container-'+category+'" class="palette-category palette-close hide">'+
'<div id="palette-header-'+category+'" class="palette-header"><i class="expanded fa fa-angle-down"></i><span>'+label+'</span></div>'+
'<div class="palette-content" id="palette-base-category-'+category+'">'+
'<div id="palette-'+category+'-input"></div>'+
'<div id="palette-'+category+'-output"></div>'+
'<div id="palette-'+category+'-function"></div>'+
'</div>'+
'</div>').appendTo("#palette-container");
categoryContainers[category] = {
container: catDiv,
close: function() {
catDiv.removeClass("palette-open");
catDiv.addClass("palette-closed");
$("#palette-base-category-"+category).slideUp();
$("#palette-header-"+category+" i").removeClass("expanded");
},
open: function() {
catDiv.addClass("palette-open");
catDiv.removeClass("palette-closed");
$("#palette-base-category-"+category).slideDown();
$("#palette-header-"+category+" i").addClass("expanded");
},
toggle: function() {
if (catDiv.hasClass("palette-open")) {
categoryContainers[category].close();
} else {
categoryContainers[category].open();
}
}
};
$("#palette-header-"+category).on('click', function(e) {
categoryContainers[category].toggle();
});
}
function setLabel(type, el,label, info) {
var nodeWidth = 82;
var nodeHeight = 25;
var lineHeight = 20;
var portHeight = 10;
var words = label.split(" ");
var displayLines = [];
var currentLine = words[0];
var currentLineWidth = RED.view.calculateTextWidth(currentLine, "palette_label", 0);
for (var i=1;i<words.length;i++) {
var newWidth = RED.view.calculateTextWidth(currentLine+" "+words[i], "palette_label", 0);
if (newWidth < nodeWidth) {
currentLine += " "+words[i];
currentLineWidth = newWidth;
} else {
displayLines.push(currentLine);
currentLine = words[i];
currentLineWidth = RED.view.calculateTextWidth(currentLine, "palette_label", 0);
}
}
displayLines.push(currentLine);
var lines = displayLines.join("<br/>");
var multiLineNodeHeight = 8+(lineHeight*displayLines.length);
el.css({height:multiLineNodeHeight+"px"});
var labelElement = el.find(".palette_label");
labelElement.html(lines);
el.find(".palette_port").css({top:(multiLineNodeHeight/2-5)+"px"});
var popOverContent;
try {
var l = "<p><b>"+label+"</b></p>";
if (label != type) {
l = "<p><b>"+label+"</b><br/><i>"+type+"</i></p>";
}
popOverContent = $(l+(info?info:$("script[data-help-name|='"+type+"']").html()||"<p>"+RED._("palette.noInfo")+"</p>").trim())
.filter(function(n) {
return (this.nodeType == 1 && this.nodeName == "P") || (this.nodeType == 3 && this.textContent.trim().length > 0)
}).slice(0,2);
} catch(err) {
// Malformed HTML may cause errors. TODO: need to understand what can break
// NON-NLS: internal debug
console.log("Error generating pop-over label for ",type);
console.log(err.toString());
popOverContent = "<p><b>"+label+"</b></p><p>"+RED._("palette.noInfo")+"</p>";
}
el.data('popover').setContent(popOverContent);
}
function escapeNodeType(nt) {
return nt.replace(" ","_").replace(".","_").replace(":","_");
}
function addNodeType(nt,def) {
var nodeTypeId = escapeNodeType(nt);
if ($("#palette_node_"+nodeTypeId).length) {
return;
}
if (exclusion.indexOf(def.category)===-1) {
var category = def.category.replace(" ","_");
var rootCategory = category.split("-")[0];
var d = document.createElement("div");
d.id = "palette_node_"+nodeTypeId;
d.type = nt;
var label;
if (typeof def.paletteLabel === "undefined") {
label = /^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1];
} else {
label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||"";
}
$('<div/>',{class:"palette_label"+(def.align=="right"?" palette_label_right":"")}).appendTo(d);
d.className="palette_node";
if (def.icon) {
var icon_url = (typeof def.icon === "function" ? def.icon.call({}) : def.icon);
var iconContainer = $('<div/>',{class:"palette_icon_container"+(def.align=="right"?" palette_icon_container_right":"")}).appendTo(d);
$('<div/>',{class:"palette_icon",style:"background-image: url(icons/"+icon_url+")"}).appendTo(iconContainer);
}
d.style.backgroundColor = def.color;
if (def.outputs > 0) {
var portOut = document.createElement("div");
portOut.className = "palette_port palette_port_output";
d.appendChild(portOut);
}
if (def.inputs > 0) {
var portIn = document.createElement("div");
portIn.className = "palette_port palette_port_input";
d.appendChild(portIn);
}
if ($("#palette-base-category-"+rootCategory).length === 0) {
if(core.indexOf(rootCategory) !== -1){
createCategoryContainer(rootCategory, RED._("node-red:palette.label."+rootCategory, {defaultValue:rootCategory}));
} else {
var ns = def.set.id;
createCategoryContainer(rootCategory, RED._(ns+":palette.label."+rootCategory, {defaultValue:rootCategory}));
}
}
$("#palette-container-"+rootCategory).show();
if ($("#palette-"+category).length === 0) {
$("#palette-base-category-"+rootCategory).append('<div id="palette-'+category+'"></div>');
}
$("#palette-"+category).append(d);
d.onmousedown = function(e) { e.preventDefault(); };
RED.popover.create({
target:$(d),
content: "hi",
delay: { show: 750, hide: 50 }
});
// $(d).popover({
// title:d.type,
// placement:"right",
// trigger: "hover",
// delay: { show: 750, hide: 50 },
// html: true,
// container:'body'
// });
$(d).click(function() {
RED.view.focus();
var helpText;
if (nt.indexOf("subflow:") === 0) {
helpText = marked(RED.nodes.subflow(nt.substring(8)).info||"");
} else {
helpText = $("script[data-help-name|='"+d.type+"']").html()||"";
}
var help = '<div class="node-help">'+helpText+"</div>";
RED.sidebar.info.set(help);
});
$(d).draggable({
helper: 'clone',
appendTo: 'body',
revert: true,
revertDuration: 50,
start: function() {RED.view.focus();}
});
var nodeInfo = null;
if (def.category == "subflows") {
$(d).dblclick(function(e) {
RED.workspaces.show(nt.substring(8));
e.preventDefault();
});
nodeInfo = marked(def.info||"");
}
setLabel(nt,$(d),label,nodeInfo);
var categoryNode = $("#palette-container-"+category);
if (categoryNode.find(".palette_node").length === 1) {
categoryContainers[category].open();
}
}
}
function removeNodeType(nt) {
var nodeTypeId = escapeNodeType(nt);
var paletteNode = $("#palette_node_"+nodeTypeId);
var categoryNode = paletteNode.closest(".palette-category");
paletteNode.remove();
if (categoryNode.find(".palette_node").length === 0) {
if (categoryNode.find("i").hasClass("expanded")) {
categoryNode.find(".palette-content").slideToggle();
categoryNode.find("i").toggleClass("expanded");
}
}
}
function hideNodeType(nt) {
var nodeTypeId = escapeNodeType(nt);
$("#palette_node_"+nodeTypeId).hide();
}
function showNodeType(nt) {
var nodeTypeId = escapeNodeType(nt);
$("#palette_node_"+nodeTypeId).show();
}
function refreshNodeTypes() {
RED.nodes.eachSubflow(function(sf) {
var paletteNode = $("#palette_node_subflow_"+sf.id.replace(".","_"));
var portInput = paletteNode.find(".palette_port_input");
var portOutput = paletteNode.find(".palette_port_output");
if (portInput.length === 0 && sf.in.length > 0) {
var portIn = document.createElement("div");
portIn.className = "palette_port palette_port_input";
paletteNode.append(portIn);
} else if (portInput.length !== 0 && sf.in.length === 0) {
portInput.remove();
}
if (portOutput.length === 0 && sf.out.length > 0) {
var portOut = document.createElement("div");
portOut.className = "palette_port palette_port_output";
paletteNode.append(portOut);
} else if (portOutput.length !== 0 && sf.out.length === 0) {
portOutput.remove();
}
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,marked(sf.info||""));
});
}
function filterChange() {
var val = $("#palette-search-input").val();
if (val === "") {
$("#palette-search-clear").hide();
} else {
$("#palette-search-clear").show();
}
var re = new RegExp(val,'i');
$(".palette_node").each(function(i,el) {
var currentLabel = $(el).find(".palette_label").text();
if (val === "" || re.test(el.id) || re.test(currentLabel)) {
$(this).show();
} else {
$(this).hide();
}
});
for (var category in categoryContainers) {
if (categoryContainers.hasOwnProperty(category)) {
if (categoryContainers[category].container
.find(".palette_node")
.filter(function() { return $(this).css('display') !== 'none'}).length === 0) {
categoryContainers[category].close();
} else {
categoryContainers[category].open();
}
}
}
}
function init() {
$(".palette-spinner").show();
if (RED.settings.paletteCategories) {
RED.settings.paletteCategories.forEach(function(category){
createCategoryContainer(category, RED._("palette.label."+category,{defaultValue:category}));
});
} else {
core.forEach(function(category){
createCategoryContainer(category, RED._("palette.label."+category,{defaultValue:category}));
});
}
$("#palette-search-input").focus(function(e) {
RED.keyboard.disable();
});
$("#palette-search-input").blur(function(e) {
RED.keyboard.enable();
});
$("#palette-search-clear").on("click",function(e) {
e.preventDefault();
$("#palette-search-input").val("");
filterChange();
$("#palette-search-input").focus();
});
$("#palette-search-input").val("");
$("#palette-search-input").on("keyup",function() {
filterChange();
});
$("#palette-search-input").on("focus",function() {
$("body").one("mousedown",function() {
$("#palette-search-input").blur();
});
});
$("#palette-collapse-all").on("click", function(e) {
e.preventDefault();
for (var cat in categoryContainers) {
if (categoryContainers.hasOwnProperty(cat)) {
categoryContainers[cat].close();
}
}
});
$("#palette-expand-all").on("click", function(e) {
e.preventDefault();
for (var cat in categoryContainers) {
if (categoryContainers.hasOwnProperty(cat)) {
categoryContainers[cat].open();
}
}
});
}
return {
init: init,
add:addNodeType,
remove:removeNodeType,
hide:hideNodeType,
show:showNodeType,
refresh:refreshNodeTypes
};
})();

79
editor/js/ui/popover.js Normal file
View File

@@ -0,0 +1,79 @@
/**
* Copyright 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.popover = (function() {
function createPopover(options) {
var target = options.target;
var content = options.content;
var delay = options.delay;
var timer = null;
var active;
var div;
var openPopup = function() {
if (active) {
div = $('<div class="red-ui-popover"></div>').html(content).appendTo("body");
var targetPos = target.offset();
var targetWidth = target.width();
var targetHeight = target.height();
var divHeight = div.height();
div.css({top: targetPos.top+targetHeight/2-divHeight/2-10,left:targetPos.left+targetWidth+17});
div.fadeIn("fast");
}
}
var closePopup = function() {
if (!active) {
if (div) {
div.fadeOut("fast",function() {
$(this).remove();
});
div = null;
}
}
}
target.on('mouseenter',function(e) {
clearTimeout(timer);
active = true;
timer = setTimeout(openPopup,delay.show);
});
target.on('mouseleave', function(e) {
if (timer) {
clearTimeout(timer);
}
active = false;
setTimeout(closePopup,delay.hide);
});
var res = {
setContent: function(_content) {
content = _content;
}
}
target.data('popover',res);
return res;
}
return {
create: createPopover
}
})();

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2013 IBM Corp.
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,24 +20,69 @@ RED.sidebar = (function() {
id:"sidebar-tabs",
onchange:function(tab) {
$("#sidebar-content").children().hide();
$("#"+tab.id).show();
if (tab.onchange) {
tab.onchange.call(tab);
}
$(tab.content).show();
},
onremove: function(tab) {
$("#"+tab.id).remove();
}
$(tab.content).hide();
if (tab.onremove) {
tab.onremove.call(tab);
}
},
minimumActiveTabWidth: 110
});
function addTab(title,content,closeable) {
$("#sidebar-content").append(content);
$(content).hide();
sidebar_tabs.addTab({id:"tab-"+title,label:title,closeable:closeable});
//content.style.position = "absolute";
//$('#sidebar').tabs("refresh");
var knownTabs = {
};
function addTab(title,content,closeable,visible) {
var options;
if (typeof title === "string") {
// TODO: legacy support in case anyone uses this...
options = {
id: content.id,
label: title,
name: title,
content: content,
closeable: closeable,
visible: visible
}
} else if (typeof title === "object") {
options = title;
}
$("#sidebar-content").append(options.content);
$(options.content).hide();
var id = options.id;
RED.menu.addItem("menu-item-sidebar-menu",{
id:"menu-item-sidebar-menu-"+options.id,
label:options.name,
onselect:function() {
showSidebar(options.id);
},
group: "sidebar-tabs"
});
knownTabs[options.id] = options;
if (options.visible !== false) {
sidebar_tabs.addTab(knownTabs[options.id]);
}
}
function removeTab(title) {
sidebar_tabs.removeTab("tab-"+title);
function removeTab(id) {
sidebar_tabs.removeTab(id);
$(knownTabs[id].content).remove();
delete knownTabs[id];
RED.menu.removeItem("menu-item-sidebar-menu-"+id);
}
var sidebarSeparator = {};
$("#sidebar-separator").draggable({
axis: "x",
@@ -50,27 +95,24 @@ RED.sidebar = (function() {
sidebarSeparator.chartRight = winWidth-$("#workspace").width()-$("#workspace").offset().left-2;
if (!RED.menu.isSelected("btn-sidebar")) {
if (!RED.menu.isSelected("menu-item-sidebar")) {
sidebarSeparator.opening = true;
var newChartRight = 15;
var newChartRight = 7;
$("#sidebar").addClass("closing");
$("#workspace").css("right",newChartRight);
$("#chart-zoom-controls").css("right",newChartRight+20);
$("#sidebar").width(0);
RED.menu.setSelected("btn-sidebar",true);
RED.view.resize();
RED.menu.setSelected("menu-item-sidebar",true);
RED.events.emit("sidebar:resize");
}
sidebarSeparator.width = $("#sidebar").width();
},
drag: function(event,ui) {
var d = ui.position.left-sidebarSeparator.start;
var newSidebarWidth = sidebarSeparator.width-d;
if (sidebarSeparator.opening) {
newSidebarWidth -= 13;
newSidebarWidth -= 3;
}
if (newSidebarWidth > 150) {
if (sidebarSeparator.chartWidth+d < 200) {
ui.position.left = 200+sidebarSeparator.start-sidebarSeparator.chartWidth;
@@ -78,7 +120,7 @@ RED.sidebar = (function() {
newSidebarWidth = sidebarSeparator.width-d;
}
}
if (newSidebarWidth < 150) {
if (!sidebarSeparator.closing) {
$("#sidebar").addClass("closing");
@@ -96,59 +138,68 @@ RED.sidebar = (function() {
var newChartRight = sidebarSeparator.chartRight-d;
$("#workspace").css("right",newChartRight);
$("#chart-zoom-controls").css("right",newChartRight+20);
$("#sidebar").width(newSidebarWidth);
sidebar_tabs.resize();
RED.view.resize();
RED.events.emit("sidebar:resize");
},
stop:function(event,ui) {
RED.view.resize();
if (sidebarSeparator.closing) {
$("#sidebar").removeClass("closing");
RED.menu.setSelected("btn-sidebar",false);
RED.menu.setSelected("menu-item-sidebar",false);
if ($("#sidebar").width() < 180) {
$("#sidebar").width(180);
$("#workspace").css("right",208);
$("#chart-zoom-controls").css("right",228);
$("#workspace").css("right",187);
}
}
$("#sidebar-separator").css("left","auto");
$("#sidebar-separator").css("right",($("#sidebar").width()+13)+"px");
$("#sidebar-separator").css("right",($("#sidebar").width()+2)+"px");
RED.events.emit("sidebar:resize");
}
});
function toggleSidebar(state) {
if (!state) {
$("#main-container").addClass("sidebar-closed");
} else {
$("#main-container").removeClass("sidebar-closed");
sidebar_tabs.resize();
}
RED.events.emit("sidebar:resize");
}
function showSidebar(id) {
if (id) {
if (!containsTab(id)) {
sidebar_tabs.addTab(knownTabs[id]);
}
sidebar_tabs.activateTab(id);
if (!RED.menu.isSelected("menu-item-sidebar")) {
RED.menu.setSelected("menu-item-sidebar",true);
}
}
}
function showSidebar(id) {
RED.menu.setSelected("btn-sidebar",true);
sidebar_tabs.activateTab("tab-"+id);
}
function containsTab(id) {
return sidebar_tabs.contains("tab-"+id);
}
$(function() {
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){RED.menu.setSelected("btn-sidebar",!RED.menu.isSelected("btn-sidebar"));d3.event.preventDefault();});
showSidebar("info");
});
function containsTab(id) {
return sidebar_tabs.contains(id);
}
function init () {
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){RED.menu.setSelected("menu-item-sidebar",!RED.menu.isSelected("menu-item-sidebar"));d3.event.preventDefault();});
showSidebar();
RED.sidebar.info.init();
RED.sidebar.config.init();
// hide info bar at start if screen rather narrow...
if ($(window).width() < 600) { toggleSidebar(); }
}
return {
init: init,
addTab: addTab,
removeTab: removeTab,
show: showSidebar,
containsTab: containsTab,
toggleSidebar: toggleSidebar
toggleSidebar: toggleSidebar,
}
})();

608
editor/js/ui/subflow.js Normal file
View File

@@ -0,0 +1,608 @@
/**
* Copyright 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.subflow = (function() {
function getSubflow() {
return RED.nodes.subflow(RED.workspaces.active());
}
function findAvailableSubflowIOPosition(subflow,isInput) {
var pos = {x:50,y:30};
if (!isInput) {
pos.x += 110;
}
for (var i=0;i<subflow.out.length+subflow.in.length;i++) {
var port;
if (i < subflow.out.length) {
port = subflow.out[i];
} else {
port = subflow.in[i-subflow.out.length];
}
if (port.x == pos.x && port.y == pos.y) {
pos.x += 55;
i=0;
}
}
return pos;
}
function addSubflowInput() {
var subflow = RED.nodes.subflow(RED.workspaces.active());
if (subflow.in.length === 1) {
return;
}
var position = findAvailableSubflowIOPosition(subflow,true);
var newInput = {
type:"subflow",
direction:"in",
z:subflow.id,
i:subflow.in.length,
x:position.x,
y:position.y,
id:RED.nodes.id()
};
var oldInCount = subflow.in.length;
subflow.in.push(newInput);
subflow.dirty = true;
var wasDirty = RED.nodes.dirty();
var wasChanged = subflow.changed;
subflow.changed = true;
var result = refresh(true);
var historyEvent = {
t:'edit',
node:subflow,
dirty:wasDirty,
changed:wasChanged,
subflow: {
inputCount: oldInCount,
instances: result.instances
}
};
RED.history.push(historyEvent);
RED.view.select();
RED.nodes.dirty(true);
RED.view.redraw();
$("#workspace-subflow-input-add").addClass("active");
$("#workspace-subflow-input-remove").removeClass("active");
}
function removeSubflowInput() {
var activeSubflow = RED.nodes.subflow(RED.workspaces.active());
if (activeSubflow.in.length === 0) {
return;
}
var removedInput = activeSubflow.in[0];
var removedInputLinks = [];
RED.nodes.eachLink(function(l) {
if (l.source.type == "subflow" && l.source.z == activeSubflow.id && l.source.i == removedInput.i) {
removedInputLinks.push(l);
} else if (l.target.type == "subflow:"+activeSubflow.id) {
removedInputLinks.push(l);
}
});
removedInputLinks.forEach(function(l) { RED.nodes.removeLink(l)});
activeSubflow.in = [];
$("#workspace-subflow-input-add").removeClass("active");
$("#workspace-subflow-input-remove").addClass("active");
activeSubflow.changed = true;
return {subflowInputs: [ removedInput ], links:removedInputLinks};
}
function addSubflowOutput(id) {
var subflow = RED.nodes.subflow(RED.workspaces.active());
var position = findAvailableSubflowIOPosition(subflow,false);
var newOutput = {
type:"subflow",
direction:"out",
z:subflow.id,
i:subflow.out.length,
x:position.x,
y:position.y,
id:RED.nodes.id()
};
var oldOutCount = subflow.out.length;
subflow.out.push(newOutput);
subflow.dirty = true;
var wasDirty = RED.nodes.dirty();
var wasChanged = subflow.changed;
subflow.changed = true;
var result = refresh(true);
var historyEvent = {
t:'edit',
node:subflow,
dirty:wasDirty,
changed:wasChanged,
subflow: {
outputCount: oldOutCount,
instances: result.instances
}
};
RED.history.push(historyEvent);
RED.view.select();
RED.nodes.dirty(true);
RED.view.redraw();
$("#workspace-subflow-output .spinner-value").html(subflow.out.length);
}
function removeSubflowOutput(removedSubflowOutputs) {
var activeSubflow = RED.nodes.subflow(RED.workspaces.active());
if (activeSubflow.out.length === 0) {
return;
}
if (typeof removedSubflowOutputs === "undefined") {
removedSubflowOutputs = [activeSubflow.out[activeSubflow.out.length-1]];
}
var removedLinks = [];
removedSubflowOutputs.sort(function(a,b) { return b.i-a.i});
for (i=0;i<removedSubflowOutputs.length;i++) {
var output = removedSubflowOutputs[i];
activeSubflow.out.splice(output.i,1);
var subflowRemovedLinks = [];
var subflowMovedLinks = [];
RED.nodes.eachLink(function(l) {
if (l.target.type == "subflow" && l.target.z == activeSubflow.id && l.target.i == output.i) {
subflowRemovedLinks.push(l);
}
if (l.source.type == "subflow:"+activeSubflow.id) {
if (l.sourcePort == output.i) {
subflowRemovedLinks.push(l);
} else if (l.sourcePort > output.i) {
subflowMovedLinks.push(l);
}
}
});
subflowRemovedLinks.forEach(function(l) { RED.nodes.removeLink(l)});
subflowMovedLinks.forEach(function(l) { l.sourcePort--; });
removedLinks = removedLinks.concat(subflowRemovedLinks);
for (var j=output.i;j<activeSubflow.out.length;j++) {
activeSubflow.out[j].i--;
activeSubflow.out[j].dirty = true;
}
}
activeSubflow.changed = true;
return {subflowOutputs: removedSubflowOutputs, links: removedLinks}
}
function refresh(markChange) {
var activeSubflow = RED.nodes.subflow(RED.workspaces.active());
refreshToolbar(activeSubflow);
var subflowInstances = [];
if (activeSubflow) {
RED.nodes.filterNodes({type:"subflow:"+activeSubflow.id}).forEach(function(n) {
subflowInstances.push({
id: n.id,
changed: n.changed
});
if (markChange) {
n.changed = true;
}
n.inputs = activeSubflow.in.length;
n.outputs = activeSubflow.out.length;
while (n.outputs < n.ports.length) {
n.ports.pop();
}
n.resize = true;
n.dirty = true;
RED.editor.updateNodeProperties(n);
});
RED.editor.validateNode(activeSubflow);
return {
instances: subflowInstances
}
}
}
function refreshToolbar(activeSubflow) {
if (activeSubflow) {
$("#workspace-subflow-input-add").toggleClass("active", activeSubflow.in.length !== 0);
$("#workspace-subflow-input-remove").toggleClass("active",activeSubflow.in.length === 0);
$("#workspace-subflow-output .spinner-value").html(activeSubflow.out.length);
}
}
function showWorkspaceToolbar(activeSubflow) {
var toolbar = $("#workspace-toolbar");
toolbar.empty();
$('<a class="button" id="workspace-subflow-edit" href="#" data-i18n="[append]subflow.editSubflowProperties"><i class="fa fa-pencil"></i> </a>').appendTo(toolbar);
$('<span style="margin-left: 5px;" data-i18n="subflow.input"></span> '+
'<div style="display: inline-block;" class="button-group">'+
'<a id="workspace-subflow-input-remove" class="button active" href="#">0</a>'+
'<a id="workspace-subflow-input-add" class="button" href="#">1</a>'+
'</div>').appendTo(toolbar);
$('<span style="margin-left: 5px;" data-i18n="subflow.output"></span> <div id="workspace-subflow-output" style="display: inline-block;" class="button-group spinner-group">'+
'<a id="workspace-subflow-output-remove" class="button" href="#"><i class="fa fa-minus"></i></a>'+
'<div class="spinner-value">3</div>'+
'<a id="workspace-subflow-output-add" class="button" href="#"><i class="fa fa-plus"></i></a>'+
'</div>').appendTo(toolbar);
// $('<a class="button disabled" id="workspace-subflow-add-input" href="#" data-i18n="[append]subflow.input"><i class="fa fa-plus"></i> </a>').appendTo(toolbar);
// $('<a class="button" id="workspace-subflow-add-output" href="#" data-i18n="[append]subflow.output"><i class="fa fa-plus"></i> </a>').appendTo(toolbar);
$('<a class="button" id="workspace-subflow-delete" href="#" data-i18n="[append]subflow.deleteSubflow"><i class="fa fa-trash"></i> </a>').appendTo(toolbar);
toolbar.i18n();
$("#workspace-subflow-output-remove").click(function(event) {
event.preventDefault();
var wasDirty = RED.nodes.dirty();
var wasChanged = activeSubflow.changed;
var result = removeSubflowOutput();
if (result) {
var inst = refresh(true);
RED.history.push({
t:'delete',
links:result.links,
subflowOutputs: result.subflowOutputs,
changed: wasChanged,
dirty:wasDirty,
subflow: {
instances: inst.instances
}
});
RED.view.select();
RED.nodes.dirty(true);
RED.view.redraw(true);
}
});
$("#workspace-subflow-output-add").click(function(event) {
event.preventDefault();
addSubflowOutput();
});
$("#workspace-subflow-input-add").click(function(event) {
event.preventDefault();
addSubflowInput();
});
$("#workspace-subflow-input-remove").click(function(event) {
event.preventDefault();
var wasDirty = RED.nodes.dirty();
var wasChanged = activeSubflow.changed;
activeSubflow.changed = true;
var result = removeSubflowInput();
if (result) {
var inst = refresh(true);
RED.history.push({
t:'delete',
links:result.links,
changed: wasChanged,
subflowInputs: result.subflowInputs,
dirty:wasDirty,
subflow: {
instances: inst.instances
}
});
RED.view.select();
RED.nodes.dirty(true);
RED.view.redraw(true);
}
});
$("#workspace-subflow-edit").click(function(event) {
RED.editor.editSubflow(RED.nodes.subflow(RED.workspaces.active()));
event.preventDefault();
});
$("#workspace-subflow-delete").click(function(event) {
event.preventDefault();
var removedNodes = [];
var removedLinks = [];
var startDirty = RED.nodes.dirty();
var activeSubflow = getSubflow();
RED.nodes.eachNode(function(n) {
if (n.type == "subflow:"+activeSubflow.id) {
removedNodes.push(n);
}
if (n.z == activeSubflow.id) {
removedNodes.push(n);
}
});
RED.nodes.eachConfig(function(n) {
if (n.z == activeSubflow.id) {
removedNodes.push(n);
}
});
var removedConfigNodes = [];
for (var i=0;i<removedNodes.length;i++) {
var removedEntities = RED.nodes.remove(removedNodes[i].id);
removedLinks = removedLinks.concat(removedEntities.links);
removedConfigNodes = removedConfigNodes.concat(removedEntities.nodes);
}
// TODO: this whole delete logic should be in RED.nodes.removeSubflow..
removedNodes = removedNodes.concat(removedConfigNodes);
RED.nodes.removeSubflow(activeSubflow);
RED.history.push({
t:'delete',
nodes:removedNodes,
links:removedLinks,
subflow: {
subflow: activeSubflow
},
dirty:startDirty
});
RED.workspaces.remove(activeSubflow);
RED.nodes.dirty(true);
RED.view.redraw();
});
refreshToolbar(activeSubflow);
$("#chart").css({"margin-top": "40px"});
$("#workspace-toolbar").show();
}
function hideWorkspaceToolbar() {
$("#workspace-toolbar").hide().empty();
$("#chart").css({"margin-top": "0"});
}
function init() {
RED.events.on("workspace:change",function(event) {
var activeSubflow = RED.nodes.subflow(event.workspace);
if (activeSubflow) {
showWorkspaceToolbar(activeSubflow);
} else {
hideWorkspaceToolbar();
}
});
RED.events.on("view:selection-changed",function(selection) {
if (!selection.nodes) {
RED.menu.setDisabled("menu-item-subflow-convert",true);
} else {
RED.menu.setDisabled("menu-item-subflow-convert",false);
}
});
}
function createSubflow() {
var lastIndex = 0;
RED.nodes.eachSubflow(function(sf) {
var m = (new RegExp("^Subflow (\\d+)$")).exec(sf.name);
if (m) {
lastIndex = Math.max(lastIndex,m[1]);
}
});
var name = "Subflow "+(lastIndex+1);
var subflowId = RED.nodes.id();
var subflow = {
type:"subflow",
id:subflowId,
name:name,
info:"",
in: [],
out: []
};
RED.nodes.addSubflow(subflow);
RED.history.push({
t:'createSubflow',
subflow: {
subflow:subflow
},
dirty:RED.nodes.dirty()
});
RED.workspaces.show(subflowId);
RED.nodes.dirty(true);
}
function convertToSubflow() {
var selection = RED.view.selection();
if (!selection.nodes) {
RED.notify(RED._("subflow.errors.noNodesSelected"),"error");
return;
}
var i;
var nodes = {};
var new_links = [];
var removedLinks = [];
var candidateInputs = [];
var candidateOutputs = [];
var candidateInputNodes = {};
var boundingBox = [selection.nodes[0].x,
selection.nodes[0].y,
selection.nodes[0].x,
selection.nodes[0].y];
for (i=0;i<selection.nodes.length;i++) {
var n = selection.nodes[i];
nodes[n.id] = {n:n,outputs:{}};
boundingBox = [
Math.min(boundingBox[0],n.x),
Math.min(boundingBox[1],n.y),
Math.max(boundingBox[2],n.x),
Math.max(boundingBox[3],n.y)
]
}
var center = [(boundingBox[2]+boundingBox[0]) / 2,(boundingBox[3]+boundingBox[1]) / 2];
RED.nodes.eachLink(function(link) {
if (nodes[link.source.id] && nodes[link.target.id]) {
// A link wholely within the selection
}
if (nodes[link.source.id] && !nodes[link.target.id]) {
// An outbound link from the selection
candidateOutputs.push(link);
removedLinks.push(link);
}
if (!nodes[link.source.id] && nodes[link.target.id]) {
// An inbound link
candidateInputs.push(link);
candidateInputNodes[link.target.id] = link.target;
removedLinks.push(link);
}
});
var outputs = {};
candidateOutputs = candidateOutputs.filter(function(v) {
if (outputs[v.source.id+":"+v.sourcePort]) {
outputs[v.source.id+":"+v.sourcePort].targets.push(v.target);
return false;
}
v.targets = [];
v.targets.push(v.target);
outputs[v.source.id+":"+v.sourcePort] = v;
return true;
});
candidateOutputs.sort(function(a,b) { return a.source.y-b.source.y});
if (Object.keys(candidateInputNodes).length > 1) {
RED.notify(RED._("subflow.errors.multipleInputsToSelection"),"error");
return;
}
var lastIndex = 0;
RED.nodes.eachSubflow(function(sf) {
var m = (new RegExp("^Subflow (\\d+)$")).exec(sf.name);
if (m) {
lastIndex = Math.max(lastIndex,m[1]);
}
});
var name = "Subflow "+(lastIndex+1);
var subflowId = RED.nodes.id();
var subflow = {
type:"subflow",
id:subflowId,
name:name,
info:"",
in: Object.keys(candidateInputNodes).map(function(v,i) { var index = i; return {
type:"subflow",
direction:"in",
x:candidateInputNodes[v].x-(candidateInputNodes[v].w/2)-80,
y:candidateInputNodes[v].y,
z:subflowId,
i:index,
id:RED.nodes.id(),
wires:[{id:candidateInputNodes[v].id}]
}}),
out: candidateOutputs.map(function(v,i) { var index = i; return {
type:"subflow",
direction:"in",
x:v.source.x+(v.source.w/2)+80,
y:v.source.y,
z:subflowId,
i:index,
id:RED.nodes.id(),
wires:[{id:v.source.id,port:v.sourcePort}]
}})
};
RED.nodes.addSubflow(subflow);
var subflowInstance = {
id:RED.nodes.id(),
type:"subflow:"+subflow.id,
x: center[0],
y: center[1],
z: RED.workspaces.active(),
inputs: subflow.in.length,
outputs: subflow.out.length,
h: Math.max(30/*node_height*/,(subflow.out.length||0) * 15),
changed:true
}
subflowInstance._def = RED.nodes.getType(subflowInstance.type);
RED.editor.validateNode(subflowInstance);
RED.nodes.add(subflowInstance);
candidateInputs.forEach(function(l) {
var link = {source:l.source, sourcePort:l.sourcePort, target: subflowInstance};
new_links.push(link);
RED.nodes.addLink(link);
});
candidateOutputs.forEach(function(output,i) {
output.targets.forEach(function(target) {
var link = {source:subflowInstance, sourcePort:i, target: target};
new_links.push(link);
RED.nodes.addLink(link);
});
});
subflow.in.forEach(function(input) {
input.wires.forEach(function(wire) {
var link = {source: input, sourcePort: 0, target: RED.nodes.node(wire.id) }
new_links.push(link);
RED.nodes.addLink(link);
});
});
subflow.out.forEach(function(output,i) {
output.wires.forEach(function(wire) {
var link = {source: RED.nodes.node(wire.id), sourcePort: wire.port , target: output }
new_links.push(link);
RED.nodes.addLink(link);
});
});
for (i=0;i<removedLinks.length;i++) {
RED.nodes.removeLink(removedLinks[i]);
}
for (i=0;i<selection.nodes.length;i++) {
selection.nodes[i].z = subflow.id;
}
RED.history.push({
t:'createSubflow',
nodes:[subflowInstance.id],
links:new_links,
subflow: {
subflow: subflow
},
activeWorkspace: RED.workspaces.active(),
removedLinks: removedLinks,
dirty:RED.nodes.dirty()
});
RED.editor.validateNode(subflow);
RED.nodes.dirty(true);
RED.view.redraw(true);
}
return {
init: init,
createSubflow: createSubflow,
convertToSubflow: convertToSubflow,
refresh: refresh,
removeInput: removeSubflowInput,
removeOutput: removeSubflowOutput
}
})();

141
editor/js/ui/tab-config.js Normal file
View File

@@ -0,0 +1,141 @@
/**
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.sidebar.config = (function() {
var content = document.createElement("div");
content.className = "sidebar-node-config"
$('<div class="palette-category">'+
'<div class="workspace-config-node-tray-header palette-header"><i class="fa fa-angle-down expanded"></i><span data-i18n="sidebar.config.local"></span></div>'+
'<ul id="workspace-config-node-tray-locals" class="palette-content config-node-list"></ul>'+
'</div>'+
'<div class="palette-category">'+
'<div class="workspace-config-node-tray-header palette-header"><i class="fa fa-angle-down expanded"></i><span data-i18n="sidebar.config.global"></span></div>'+
'<ul id="workspace-config-node-tray-globals" class="palette-content config-node-list"></ul>'+
'</div>').appendTo(content);
function createConfigNodeList(nodes,list) {
nodes.sort(function(A,B) {
if (A.type < B.type) { return -1;}
if (A.type > B.type) { return 1;}
return 0;
});
list.empty();
if (nodes.length === 0) {
$('<li class="config_node_none" data-i18n="sidebar.config.none">NONE</li>').i18n().appendTo(list);
} else {
var currentType = "";
nodes.forEach(function(node) {
var label = "";
if (typeof node._def.label == "function") {
label = node._def.label.call(node);
} else {
label = node._def.label;
}
label = label || node.id;
if (node.type != currentType) {
$('<li class="config_node_type">'+node.type+'</li>').appendTo(list);
currentType = node.type;
}
var entry = $('<li class="palette_node config_node"></li>').appendTo(list);
$('<div class="palette_label"></div>').text(label).appendTo(entry);
var iconContainer = $('<div/>',{class:"palette_icon_container palette_icon_container_right"}).text(node.users.length).appendTo(entry);
if (node.users.length === 0) {
entry.addClass("config_node_unused");
}
entry.on('click',function(e) {
RED.sidebar.info.refresh(node);
});
entry.on('dblclick',function(e) {
RED.editor.editConfig("", node.type, node.id);
});
var userArray = node.users.map(function(n) { return n.id });
entry.on('mouseover',function(e) {
RED.nodes.eachNode(function(node) {
if( userArray.indexOf(node.id) != -1) {
node.highlighted = true;
node.dirty = true;
}
});
RED.view.redraw();
});
entry.on('mouseout',function(e) {
RED.nodes.eachNode(function(node) {
if(node.highlighted) {
node.highlighted = false;
node.dirty = true;
}
});
RED.view.redraw();
});
});
}
}
function refreshConfigNodeList() {
var localConfigNodes = [];
var globalConfigNodes = [];
RED.nodes.eachConfig(function(cn) {
if (cn.z == RED.workspaces.active()) {
localConfigNodes.push(cn);
} else if (!cn.z) {
globalConfigNodes.push(cn);
}
});
createConfigNodeList(localConfigNodes,$("#workspace-config-node-tray-locals"));
createConfigNodeList(globalConfigNodes,$("#workspace-config-node-tray-globals"));
}
function init() {
RED.sidebar.addTab({
id: "config",
label: RED._("sidebar.config.label"),
name: RED._("sidebar.config.name"),
content: content,
closeable: true,
visible: false,
onchange: function() { refreshConfigNodeList(); }
});
$(".workspace-config-node-tray-header").on('click', function(e) {
var icon = $(this).find("i");
if (icon.hasClass("expanded")) {
icon.removeClass("expanded");
$(this).next().slideUp();
} else {
icon.addClass("expanded");
$(this).next().slideDown();
}
});
}
function show() {
refreshConfigNodeList();
RED.sidebar.show("config");
}
return {
init:init,
show:show,
refresh:refreshConfigNodeList
}
})();

205
editor/js/ui/tab-info.js Normal file
View File

@@ -0,0 +1,205 @@
/**
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.sidebar.info = (function() {
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
});
var content = document.createElement("div");
content.style.paddingTop = "4px";
content.style.paddingLeft = "4px";
content.style.paddingRight = "4px";
content.className = "sidebar-node-info"
var propertiesExpanded = false;
function init() {
RED.sidebar.addTab({
id: "info",
label: RED._("sidebar.info.label"),
name: RED._("sidebar.info.name"),
content: content
});
}
function show() {
RED.sidebar.show("info");
}
function jsonFilter(key,value) {
if (key === "") {
return value;
}
var t = typeof value;
if ($.isArray(value)) {
return "[array:"+value.length+"]";
} else if (t === "object") {
return "[object]"
} else if (t === "string") {
if (value.length > 30) {
return value.substring(0,30)+" ...";
}
}
return value;
}
function refresh(node) {
var table = '<table class="node-info"><tbody>';
table += '<tr class="blank"><td colspan="2">'+RED._("sidebar.info.node")+'</td></tr>';
if (node.type != "subflow" && node.name) {
table += "<tr><td>"+RED._("common.label.name")+"</td><td>&nbsp;"+node.name+"</td></tr>";
}
table += "<tr><td>"+RED._("sidebar.info.type")+"</td><td>&nbsp;"+node.type+"</td></tr>";
table += "<tr><td>"+RED._("sidebar.info.id")+"</td><td>&nbsp;"+node.id+"</td></tr>";
var m = /^subflow(:(.+))?$/.exec(node.type);
var subflowNode;
if (m) {
if (m[2]) {
subflowNode = RED.nodes.subflow(m[2]);
} else {
subflowNode = node;
}
table += '<tr class="blank"><td colspan="2">'+RED._("sidebar.info.subflow")+'</td></tr>';
var userCount = 0;
var subflowType = "subflow:"+subflowNode.id;
RED.nodes.eachNode(function(n) {
if (n.type === subflowType) {
userCount++;
}
});
table += "<tr><td>"+RED._("common.label.name")+"</td><td>"+subflowNode.name+"</td></tr>";
table += "<tr><td>"+RED._("sidebar.info.instances")+"</td><td>"+userCount+"</td></tr>";
}
if (!m && node.type != "subflow" && node.type != "comment") {
table += '<tr class="blank"><td colspan="2"><a href="#" class="node-info-property-header"><i style="width: 10px; text-align: center;" class="fa fa-caret-'+(propertiesExpanded?"down":"right")+'"></i> '+RED._("sidebar.info.properties")+'</a></td></tr>';
if (node._def) {
for (var n in node._def.defaults) {
if (n != "name" && node._def.defaults.hasOwnProperty(n)) {
var val = node[n]||"";
var type = typeof val;
if (type === "string") {
if (val.length === 0) {
val += '<span style="font-style: italic; color: #ccc;">'+RED._("sidebar.info.blank")+'</span>';
} else {
if (val.length > 30) {
val = val.substring(0,30)+" ...";
}
val = val.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
}
} else if (type === "number") {
val = val.toString();
} else if ($.isArray(val)) {
val = "[<br/>";
for (var i=0;i<Math.min(node[n].length,10);i++) {
var vv = JSON.stringify(node[n][i],jsonFilter," ").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
val += "&nbsp;"+i+": "+vv+"<br/>";
}
if (node[n].length > 10) {
val += "&nbsp;... "+RED._("sidebar.info.arrayItems",{count:node[n].length})+"<br/>";
}
val += "]";
} else {
val = JSON.stringify(val,jsonFilter," ");
val = val.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
}
table += '<tr class="node-info-property-row'+(propertiesExpanded?"":" hide")+'"><td>'+n+"</td><td>"+val+"</td></tr>";
}
}
}
}
table += "</tbody></table><hr/>";
if (!subflowNode && node.type != "comment") {
var helpText = $("script[data-help-name|='"+node.type+"']").html()||"";
table += '<div class="node-help">'+helpText+"</div>";
}
if (subflowNode) {
table += '<div class="node-help">'+marked(subflowNode.info||"")+'</div>';
} else if (node._def && node._def.info) {
var info = node._def.info;
table += '<div class="node-help">'+marked(typeof info === "function" ? info.call(node) : info)+'</div>';
//table += '<div class="node-help">'+(typeof info === "function" ? info.call(node) : info)+'</div>';
}
$(content).html(table);
$(".node-info-property-header").click(function(e) {
var icon = $(this).find("i");
if (icon.hasClass("fa-caret-right")) {
icon.removeClass("fa-caret-right");
icon.addClass("fa-caret-down");
$(".node-info-property-row").show();
propertiesExpanded = true;
} else {
icon.addClass("fa-caret-right");
icon.removeClass("fa-caret-down");
$(".node-info-property-row").hide();
propertiesExpanded = false;
}
e.preventDefault();
});
}
function clear() {
$(content).html("");
}
function set(html) {
$(content).html(html);
}
RED.events.on("view:selection-changed",function(selection) {
if (selection.nodes) {
if (selection.nodes.length == 1) {
var node = selection.nodes[0];
if (node.type === "subflow" && node.direction) {
refresh(RED.nodes.subflow(node.z));
} else {
refresh(node);
}
}
} else {
var subflow = RED.nodes.subflow(RED.workspaces.active());
if (subflow) {
refresh(subflow);
} else {
clear();
}
}
});
return {
init: init,
show: show,
refresh:refresh,
clear: clear,
set: set
}
})();

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2013 IBM Corp.
* Copyright 2013, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,58 +13,90 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.tabs = (function() {
function createTabs(options) {
var tabs = {};
var currentTabWidth;
var currentActiveTabWidth = 0;
var ul = $("#"+options.id)
ul.addClass("red-ui-tabs");
ul.children().first().addClass("active");
ul.children().addClass("red-ui-tab");
function onTabClick() {
activateTab($(this));
return false;
}
function onTabDblClick() {
if (options.ondblclick) {
options.ondblclick(tabs[$(this).attr('href').slice(1)]);
}
return false;
}
function activateTab(link) {
if (typeof link === "string") {
link = ul.find("a[href='#"+link+"']");
}
if (!link.parent().hasClass("active")) {
ul.children().removeClass("active");
ul.children().css({"transition": "width 100ms"});
link.parent().addClass("active");
if (options.onchange) {
options.onchange(tabs[link.attr('href').slice(1)]);
}
updateTabWidths();
setTimeout(function() {
ul.children().css({"transition": ""});
},100);
}
}
function updateTabWidths() {
var tabs = ul.find("li.red-ui-tab");
var width = ul.width();
var tabCount = tabs.size();
var tabWidth = (width-6-(tabCount*7))/tabCount;
var pct = 100*tabWidth/width;
tabs.css({width:pct+"%"});
var tabWidth = (width-12-(tabCount*6))/tabCount;
currentTabWidth = 100*tabWidth/width;
currentActiveTabWidth = currentTabWidth+"%";
if (options.hasOwnProperty("minimumActiveTabWidth")) {
if (tabWidth < options.minimumActiveTabWidth) {
tabCount -= 1;
tabWidth = (width-12-options.minimumActiveTabWidth-(tabCount*6))/tabCount;
currentTabWidth = 100*tabWidth/width;
currentActiveTabWidth = options.minimumActiveTabWidth+"px";
} else {
currentActiveTabWidth = 0;
}
}
tabs.css({width:currentTabWidth+"%"});
if (tabWidth < 50) {
ul.find(".red-ui-tab-close").hide();
ul.find(".red-ui-tab-icon").hide();
} else {
ul.find(".red-ui-tab-close").show();
ul.find(".red-ui-tab-icon").show();
}
if (currentActiveTabWidth !== 0) {
ul.find("li.red-ui-tab.active").css({"width":options.minimumActiveTabWidth});
ul.find("li.red-ui-tab.active .red-ui-tab-close").show();
ul.find("li.red-ui-tab.active .red-ui-tab-icon").show();
}
}
ul.find("li.red-ui-tab a").on("click",onTabClick).on("dblclick",onTabDblClick);
updateTabWidths();
function removeTab(id) {
var li = ul.find("a[href='#"+id+"']").parent();
if (li.hasClass("active")) {
@@ -81,20 +113,23 @@ RED.tabs = (function() {
delete tabs[id];
updateTabWidths();
}
return {
addTab: function(tab) {
tabs[tab.id] = tab;
var li = $("<li/>",{class:"red-ui-tab"}).appendTo(ul);
var link = $("<a/>",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li);
link.html(tab.label);
if (tab.icon) {
$('<img src="'+tab.icon+'" class="red-ui-tab-icon"/>').appendTo(link);
}
$('<span/>').text(tab.label).appendTo(link);
link.on("click",onTabClick);
link.on("dblclick",onTabDblClick);
if (tab.closeable) {
var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li);
closeLink.html('<i class="fa fa-times" />');
closeLink.append('<i class="fa fa-times" />');
closeLink.on("click",function(event) {
removeTab(tab.id);
});
@@ -116,11 +151,18 @@ RED.tabs = (function() {
},
contains: function(id) {
return ul.find("a[href='#"+id+"']").length > 0;
},
renameTab: function(id,label) {
tabs[id].label = label;
var tab = ul.find("a[href='#"+id+"']");
tab.attr("title",label);
tab.find("span").text(label);
updateTabWidths();
}
}
}
return {
create: createTabs
}

File diff suppressed because it is too large Load Diff

257
editor/js/ui/workspaces.js Normal file
View File

@@ -0,0 +1,257 @@
/**
* Copyright 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.workspaces = (function() {
var activeWorkspace = 0;
var workspaceIndex = 0;
function addWorkspace(ws) {
if (ws) {
workspace_tabs.addTab(ws);
workspace_tabs.resize();
} else {
var tabId = RED.nodes.id();
do {
workspaceIndex += 1;
//TODO: nls of Sheet
} while($("#workspace-tabs a[title='"+RED._('workspace.defaultName',{number:workspaceIndex})+"']").size() !== 0);
ws = {type:"tab",id:tabId,label:RED._('workspace.defaultName',{number:workspaceIndex})};
RED.nodes.addWorkspace(ws);
workspace_tabs.addTab(ws);
workspace_tabs.activateTab(tabId);
RED.history.push({t:'add',workspaces:[ws],dirty:RED.nodes.dirty()});
RED.nodes.dirty(true);
}
}
function deleteWorkspace(ws,force) {
if (workspace_tabs.count() == 1) {
return;
}
var nodes = [];
if (!force) {
nodes = RED.nodes.filterNodes({z:ws.id});
}
if (force || nodes.length === 0) {
removeWorkspace(ws);
var historyEvent = RED.nodes.removeWorkspace(ws.id);
historyEvent.t = 'delete';
historyEvent.dirty = RED.nodes.dirty();
historyEvent.workspaces = [ws];
RED.history.push(historyEvent);
RED.nodes.dirty(true);
} else {
$( "#node-dialog-delete-workspace" ).dialog('option','workspace',ws);
$( "#node-dialog-delete-workspace-content" ).text(RED._("workspace.delete",{label:ws.label}));
$( "#node-dialog-delete-workspace" ).dialog('open');
}
}
function showRenameWorkspaceDialog(id) {
var ws = RED.nodes.workspace(id);
$( "#node-dialog-rename-workspace" ).dialog("option","workspace",ws);
if (workspace_tabs.count() == 1) {
$( "#node-dialog-rename-workspace").next().find(".leftButton")
.prop('disabled',true)
.addClass("ui-state-disabled");
} else {
$( "#node-dialog-rename-workspace").next().find(".leftButton")
.prop('disabled',false)
.removeClass("ui-state-disabled");
}
$( "#node-input-workspace-name" ).val(ws.label);
$( "#node-dialog-rename-workspace" ).dialog("open");
}
var workspace_tabs;
function createWorkspaceTabs(){
workspace_tabs = RED.tabs.create({
id: "workspace-tabs",
onchange: function(tab) {
var event = {
old: activeWorkspace
}
activeWorkspace = tab.id;
event.workspace = activeWorkspace;
RED.events.emit("workspace:change",event);
RED.sidebar.config.refresh();
},
ondblclick: function(tab) {
if (tab.type != "subflow") {
showRenameWorkspaceDialog(tab.id);
} else {
RED.editor.editSubflow(RED.nodes.subflow(tab.id));
}
},
onadd: function(tab) {
RED.menu.addItem("menu-item-workspace",{
id:"menu-item-workspace-menu-"+tab.id.replace(".","-"),
label:tab.label,
onselect:function() {
workspace_tabs.activateTab(tab.id);
}
});
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() == 1);
},
onremove: function(tab) {
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() == 1);
RED.menu.removeItem("menu-item-workspace-menu-"+tab.id.replace(".","-"));
},
minimumActiveTabWidth: 150
});
$("#node-dialog-rename-workspace form" ).submit(function(e) { e.preventDefault();});
$( "#node-dialog-rename-workspace" ).dialog({
modal: true,
autoOpen: false,
width: 500,
title: RED._("workspace.renameSheet"),
buttons: [
{
class: 'leftButton',
text: RED._("common.label.delete"),
click: function() {
var workspace = $(this).dialog('option','workspace');
$( this ).dialog( "close" );
deleteWorkspace(workspace);
}
},
{
text: RED._("common.label.ok"),
click: function() {
var workspace = $(this).dialog('option','workspace');
var label = $( "#node-input-workspace-name" ).val();
if (workspace.label != label) {
workspace_tabs.renameTab(workspace.id,label);
RED.nodes.dirty(true);
$("#menu-item-workspace-menu-"+workspace.id.replace(".","-")).text(label);
// TODO: update entry in menu
}
$( this ).dialog( "close" );
}
},
{
text: RED._("common.label.cancel"),
click: function() {
$( this ).dialog( "close" );
}
}
],
open: function(e) {
RED.keyboard.disable();
},
close: function(e) {
RED.keyboard.enable();
}
});
$( "#node-dialog-delete-workspace" ).dialog({
modal: true,
autoOpen: false,
width: 500,
title: RED._("workspace.confirmDelete"),
buttons: [
{
text: RED._("common.label.ok"),
click: function() {
var workspace = $(this).dialog('option','workspace');
deleteWorkspace(workspace,true);
$( this ).dialog( "close" );
}
},
{
text: RED._("common.label.cancel"),
click: function() {
$( this ).dialog( "close" );
}
}
],
open: function(e) {
RED.keyboard.disable();
},
close: function(e) {
RED.keyboard.enable();
}
});
}
function init() {
createWorkspaceTabs();
$('#btn-workspace-add-tab').on("click",function(e) {addWorkspace(); e.preventDefault()});
RED.events.on("sidebar:resize",workspace_tabs.resize);
RED.menu.setAction('menu-item-workspace-delete',function() {
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
});
$(window).resize(function() {
workspace_tabs.resize();
});
}
function removeWorkspace(ws) {
if (!ws) {
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
} else {
if (workspace_tabs.contains(ws.id)) {
workspace_tabs.removeTab(ws.id);
}
}
}
return {
init: init,
add: addWorkspace,
remove: removeWorkspace,
edit: function(id) {
showRenameWorkspaceDialog(id||activeWorkspace);
},
contains: function(id) {
return workspace_tabs.contains(id);
},
count: function() {
return workspace_tabs.count();
},
active: function() {
return activeWorkspace
},
show: function(id) {
if (!workspace_tabs.contains(id)) {
var sf = RED.nodes.subflow(id);
if (sf) {
addWorkspace({type:"subflow",id:id,icon:"red/images/subflow_tab.png",label:sf.name, closeable: true});
}
}
workspace_tabs.activateTab(id);
},
refresh: function() {
RED.nodes.eachSubflow(function(sf) {
if (workspace_tabs.contains(sf.id)) {
workspace_tabs.renameTab(sf.id,sf.name);
}
});
RED.sidebar.config.refresh();
},
resize: function() {
workspace_tabs.resize();
}
}
})();

189
editor/js/user.js Normal file
View File

@@ -0,0 +1,189 @@
/**
* Copyright 2014, 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
RED.user = (function() {
function login(opts,done) {
if (typeof opts == 'function') {
done = opts;
opts = {};
}
var dialog = $('<div id="node-dialog-login" class="hide">'+
'<div style="display: inline-block;width: 250px; vertical-align: top; margin-right: 10px; margin-bottom: 20px;"><img id="node-dialog-login-image" src=""/></div>'+
'<div style="display: inline-block; width: 250px; vertical-align: bottom; margin-left: 10px; margin-bottom: 20px;">'+
'<form id="node-dialog-login-fields" class="form-horizontal" style="margin-bottom: 0px;"></form>'+
'</div>'+
'</div>');
dialog.dialog({
autoOpen: false,
dialogClass: "ui-dialog-no-close",
modal: true,
closeOnEscape: false,
width: 600,
resizable: false,
draggable: false
});
$("#node-dialog-login-fields").empty();
$.ajax({
dataType: "json",
url: "auth/login",
success: function(data) {
if (data.type == "credentials") {
var i=0;
if (data.image) {
$("#node-dialog-login-image").attr("src",data.image);
} else {
$("#node-dialog-login-image").attr("src","red/images/node-red-256.png");
}
for (;i<data.prompts.length;i++) {
var field = data.prompts[i];
var row = $("<div/>",{id:"rrr"+i,class:"form-row"});
$('<label for="node-dialog-login-'+field.id+'">'+field.label+':</label><br/>').appendTo(row);
var input = $('<input style="width: 100%" id="node-dialog-login-'+field.id+'" type="'+field.type+'" tabIndex="'+(i+1)+'"/>').appendTo(row);
if (i<data.prompts.length-1) {
input.keypress(
(function() {
var r = row;
return function(event) {
if (event.keyCode == 13) {
r.next("div").find("input").focus();
event.preventDefault();
}
}
})()
);
}
row.appendTo("#node-dialog-login-fields");
}
$('<div class="form-row" style="text-align: right; margin-top: 10px;"><span id="node-dialog-login-failed" style="line-height: 2em;float:left;" class="hide">'+RED._("user.loginFailed")+'</span><img src="red/images/spin.svg" style="height: 30px; margin-right: 10px; " class="login-spinner hide"/>'+
(opts.cancelable?'<a href="#" id="node-dialog-login-cancel" style="margin-right: 20px;" tabIndex="'+(i+1)+'">'+RED._("common.label.cancel")+'</a>':'')+
'<input type="submit" id="node-dialog-login-submit" style="width: auto;" tabIndex="'+(i+2)+'" value="'+RED._("user.login")+'"></div>').appendTo("#node-dialog-login-fields");
$("#node-dialog-login-submit").button();
$("#node-dialog-login-fields").submit(function(event) {
$("#node-dialog-login-submit").button("option","disabled",true);
$("#node-dialog-login-failed").hide();
$(".login-spinner").show();
var body = {
client_id: "node-red-editor",
grant_type: "password",
scope:""
}
for (var i=0;i<data.prompts.length;i++) {
var field = data.prompts[i];
body[field.id] = $("#node-dialog-login-"+field.id).val();
}
$.ajax({
url:"auth/token",
type: "POST",
data: body
}).done(function(data,textStatus,xhr) {
RED.settings.set("auth-tokens",data);
$("#node-dialog-login").dialog('destroy').remove();
done();
}).fail(function(jqXHR,textStatus,errorThrown) {
RED.settings.remove("auth-tokens");
$("#node-dialog-login-failed").show();
}).always(function() {
$("#node-dialog-login-submit").button("option","disabled",false);
$(".login-spinner").hide();
});
event.preventDefault();
});
if (opts.cancelable) {
$("#node-dialog-login-cancel").button().click(function( event ) {
$("#node-dialog-login").dialog('destroy').remove();
});
}
}
dialog.dialog("open");
}
});
}
function logout() {
$.ajax({
url: "auth/revoke",
type: "POST",
data: {token:RED.settings.get("auth-tokens").access_token},
success: function() {
RED.settings.remove("auth-tokens");
document.location.reload(true);
}
})
}
function updateUserMenu() {
$("#usermenu-submenu li").remove();
if (RED.settings.user.anonymous) {
RED.menu.addItem("btn-usermenu",{
id:"usermenu-item-login",
label:RED._("menu.label.login"),
onselect: function() {
RED.user.login({cancelable:true},function() {
RED.settings.load(function() {
RED.notify(RED._("user.loggedInAs",{name:RED.settings.user.username}),"success");
updateUserMenu();
});
});
}
});
} else {
RED.menu.addItem("btn-usermenu",{
id:"usermenu-item-username",
label:"<b>"+RED.settings.user.username+"</b>"
});
RED.menu.addItem("btn-usermenu",{
id:"usermenu-item-logout",
label:RED._("menu.label.logout"),
onselect: function() {
RED.user.logout();
}
});
}
}
function init() {
if (RED.settings.user) {
if (!RED.settings.editorTheme || !RED.settings.editorTheme.hasOwnProperty("userMenu")) {
$('<li><a id="btn-usermenu" class="button hide" data-toggle="dropdown" href="#"><i class="fa fa-user"></i></a></li>')
.prependTo(".header-toolbar");
RED.menu.init({id:"btn-usermenu",
options: []
});
updateUserMenu();
}
}
}
return {
init: init,
login: login,
logout: logout
}
})();

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2014 IBM Corp.
* Copyright 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -12,4 +12,10 @@
* 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.
**/
**/
.popover-title { display: none; }
div.btn-group, a.btn {
@include disable-selection;
}

45
editor/sass/colors.scss Normal file
View File

@@ -0,0 +1,45 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
$form-placeholder-color: #bbbbbb;
$form-text-color: #444;
$form-input-focus-color: rgba(85,150,230,0.8);
$form-input-border-color: #ccc;
$node-selected-color: #ff7f0e;
$port-selected-color: #ff7f0e;
$link-color: #888;
$link-subflow-color: #bbb;
$link-unknown-color: #f00;
$primary-border-color: #bbbbbb;
$secondary-border-color: #dddddd;
$tab-background-active: #fff;
$tab-background-inactive: #f0f0f0;
$tab-background-hover: #ddd;
$palette-header-background: #f3f3f3;
$workspace-button-background: #fff;
$workspace-button-background-hover: #ddd;
$workspace-button-background-active: #efefef;
$workspace-button-color: #999;
$workspace-button-color-disabled: #ccc;
$workspace-button-color-focus: #999;
$workspace-button-color-hover: #666;
$workspace-button-color-active: #666;

37
editor/sass/dragdrop.scss Normal file
View File

@@ -0,0 +1,37 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
#dropTarget {
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
background: rgba(0,0,0,0.1);
display:table;
width: 100%;
height: 100%;
display: none;
}
#dropTarget div {
display: table-cell;
vertical-align: middle;
text-align: center;
font-size: 40px;
color: #fff;
}
#dropTarget div i {
font-size: 80px;
}

View File

@@ -0,0 +1,84 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
.dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus, .dropdown-submenu:hover>a, .dropdown-submenu:focus>a {
background: #999;
}
.dropdown-menu * .fa-check-square {
display: none;
color: #e0e0e0;
margin-left: -25px;
margin-top: 3px;
}
.dropdown-menu * a.active > .fa-check-square {
display: inline-block;
}
.dropdown-menu * .fa-square {
display: inline-block;
color: #e0e0e0;
margin-left: -25px;
margin-top: 3px;
}
.dropdown-menu * a.active > .fa-square {
display: none;
}
.dropdown-menu>li.disabled>a:hover>[class^="icon-"] {
background-image: url("vendor/bootstrap/img/glyphicons-halflings.png") !important;
}
/** Fix for unreachable dropdown menu **/
.dropdown-menu {
border-radius: 0;
width: 200px !important;
margin-left: 0px !important;
}
.dropdown-menu > li > a > i {
width: 10px;
text-align: center;
margin-left: -8px;
}
.dropdown-menu > li > a {
padding-left: 38px ;
text-indent: -8px ;
white-space: normal !important;
}
.dropdown-submenu>a:after {
display: none;
}
.dropdown-submenu>a:before {
display: block;
float: left;
width: 0;
height: 0;
margin-top: 5px;
margin-left: -30px;
border-color: transparent;
border-right-color: #e0e0e0;
border-style: solid;
border-width: 5px 5px 5px 0;
content: " ";
}
.dropdown-submenu.disabled > a:before {
border-right-color: #444;
}
.dropdown-submenu.pull-left>.dropdown-menu {
border-radius: 0;
}

106
editor/sass/editor.scss Normal file
View File

@@ -0,0 +1,106 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
.dialog-form, #dialog-form, #dialog-config-form {
margin: 0;
height: 100%;
}
.input-error {
border-color: rgb(214, 97, 95) !important;
}
.ui-dialog .ui-dialog-buttonpane button.leftButton {
margin-right: 40px;
}
.form-row {
clear: both;
color: $form-text-color;
margin-bottom:12px;
}
.form-row label {
display: inline-block;
width: 100px;
}
.form-row input {
width:70%;
}
.form-tips {
background: #ffe;
padding: 8px;
border-radius: 2px;
border: 1px solid $secondary-border-color;
max-width: 450px;
}
.form-tips code {
border: none;
padding: auto;
}
.form-tips a {
text-decoration: underline;
}
.node-text-editor {
border:1px solid #ccc;
border-radius:5px;
overflow: hidden;
font-size: 14px !important;
font-family: monospace !important;
}
.editor-button {
@include workspace-button;
height: 34px;
line-height: 32px;
font-size: 13px;
border-radius: 4px;
padding: 0 10px;
}
.editor-button-small {
height: 20px;
line-height: 18px;
font-size: 10px;
border-radius: 2px;
padding: 0 5px;
}
#node-config-dialog-scope-container {
cursor: auto;
float: right;
font-size: 12px !important;
}
#node-config-dialog-scope-warning {
display: inline-block;
margin-right: 5px;
color: #AD1625;
vertical-align: middle;
}
#node-config-dialog-scope {
margin: 1px 0 0 0;
padding: 0;
height: 22px;
width: 110px;
}
#node-config-dialog-user-count {
vertical-align: middle;
display:inline-block;
margin-top: 10px;
margin-right: 20px;
float:left;
font-size: 12px;
}

236
editor/sass/flow.scss Normal file
View File

@@ -0,0 +1,236 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
.hidden {
display: none;
}
.lasso {
stroke-width: 1px;
stroke: #ff7f0e;
fill: rgba(20,125,255,0.1);
stroke-dasharray: 10 5;
}
.group-box {
stroke-width: 1px;
stroke: #aaaaaa;
fill: rgba(208, 211, 238, 0.1);
stroke-dasharray: 3 3;
}
.group-box-active {
fill: #fff;
stroke: #ff7f0e;
}
.group_label {
stroke-width: 0;
fill: #999;
font-size: 11px;
pointer-events: none;
-webkit-touch-callout: none;
@include disable-selection;
}
.pull-right {
margin-left: 20px;
}
.node_label_italic {
font-style: italic;
}
.node_label_unknown {
font-style: italic;
fill: #e00 !important;
}
.node_label_white {
fill: #eee !important;
}
.node_label {
stroke-width: 0;
fill: #333;
font-size: 14px;
pointer-events: none;
-webkit-touch-callout: none;
@include disable-selection;
}
.port_label {
stroke-width: 0;
fill: #888;
font-size: 16px;
alignment-baseline: middle;
text-anchor: middle;
pointer-events: none;
-webkit-touch-callout: none;
@include disable-selection;
}
.function_label {
font-size: 12px;
}
.node {
stroke: #999;
cursor: move;
stroke-width: 1;
}
.node_unknown {
stroke-dasharray:10,4;
stroke: #f33;
}
.tool_arrow {
stroke-width: 1;
stroke: #999;
fill: #999;
cursor: pointer;
}
.node_tools {
fill: #ddd;
stroke: #999;
cursor: move;
stroke-width: 1;
cursor: pointer;
}
.node_tools_hovered {
stroke: #ff7f0e;
fill: #eee;
}
.node_button {
fill: inherit;
}
.port {
stroke: #999;
stroke-width: 1;
fill: #ddd;
cursor: crosshair;
}
.port_highlight {
stroke: #6DA332;
stroke-width: 3;
fill: #fff;
pointer-events:none;
fill-opacity: 0.5;
}
.node_error {
stroke: #ff0000;
stroke-width: 2;
fill: #ff7f0e;
}
.node_badge {
stroke: rgb(93, 114, 145);
stroke-width: 1;
fill: rgb(190, 209, 255);
}
.node_badge_label {
stroke-width:0;
fill: #fff;
font-size: 11px;
pointer-events: none;
-webkit-touch-callout: none;
@include disable-selection;
}
.node_invalid {
stroke: #ff0000;
}
.node_selected {
stroke-width: 2;
stroke: $node-selected-color !important;
}
.node_highlighted {
stroke: #dd1616;
stroke-width: 2;
stroke-dasharray: 10, 4;
}
.node_hovered {
}
.node_status_label {
@include disable-selection;
stroke-width: 0;
fill: #888;
font-size:9pt;
stroke:#000;
text-anchor:start;
}
.port_hovered {
stroke: $port-selected-color;
fill: $port-selected-color;
}
.subflowport {
stroke-dasharray: 5,5;
fill: #eee;
stroke: #999;
}
.drag_line {
stroke: $node-selected-color;
stroke-width: 4;
fill: none;
pointer-events: none;
}
.drag_line_hidden {
stroke: $node-selected-color;
stroke-width: 0;
pointer-events: none;
fill: none;
}
.link_line {
stroke: $link-color;
stroke-width: 3;
fill: none;
pointer-events: none;
}
.link_subflow {
stroke: $link-subflow-color;
stroke-dasharray: 10,5;
stroke-width: 2;
}
.link_outline {
stroke: #fff;
stroke-width: 4;
cursor: crosshair;
fill: none;
pointer-events: none;
}
.link_background {
stroke: #fff;
opacity: 0;
stroke-width: 20;
cursor: crosshair;
fill: none;
}
g.link_selected path.link_line {
stroke: $node-selected-color;
}
g.link_unknown path.link_line {
stroke: $link-unknown-color;
stroke-width: 2;
stroke-dasharray: 10, 4;
}

1046
editor/sass/forms.scss Normal file

File diff suppressed because it is too large Load Diff

266
editor/sass/header.scss Normal file
View File

@@ -0,0 +1,266 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
$activeButton: #121212;
$deployButton: #8C101C;
$deployButtonHover: #6E0A1E;
$deployButtonActive: #4C0A17;
$deployDisabledButton: #444;
$deployDisabledButtonHover: #555;
$deployDisabledButtonActive: #444;
$headerMenuBackground: #121212;
$headerMenuItemHover: #323232;
$headerMenuItemDivider: #464646;
#header {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 40px;
background: #000;
box-sizing: border-box;
padding: 0px 0px 0px 20px;
color: #C7C7C7;
font-size: 14px;
}
span.logo {
float: left;
margin-top: 5px;
font-size: 30px;
line-height: 30px;
text-decoration: none;
span {
vertical-align: middle;
font-size: 16px !important;
}
img {
height: 18px;
}
a {
color: inherit;
&:hover {
text-decoration: none;
}
}
}
.header-toolbar {
padding: 0;
margin: 0;
list-style: none;
float: right;
> li {
display: inline-block;
padding: 0;
margin: 0;
position: relative;
}
}
.button {
@include disable-selection;
}
#header .button {
min-width: 20px;
text-align: center;
line-height: 40px;
display: inline-block;
font-size: 20px;
padding: 0px 12px;
text-decoration: none;
color: #C7C7C7;
margin: auto 5px;
vertical-align: middle;
border-left: 2px solid #000;
border-right: 2px solid #000;
&:hover {
border-color: $headerMenuItemHover;
}
}
#header .button-group {
display: inline-block;
margin: auto 15px;
vertical-align: middle;
clear: both;
}
#header .button-group > a {
display: inline-block;
float: left;
line-height: 22px;
font-size: 14px;
text-decoration: none;
padding: 4px 8px;
margin: 0;
}
.deploy-button {
background: $deployButton;
color: #eee !important;
&:hover {
background: $deployButtonHover;
}
&:active {
background: $deployButtonActive;
color: #ccc !important;
}
}
#btn-deploy {
padding: 4px 12px;
&.disabled {
cursor: default;
background: $deployDisabledButton;
color: #999 !important;
img {
opacity: 0.3;
}
&+ #btn-deploy-options {
background: $deployDisabledButton;
color: #ddd;
}
&+ #btn-deploy-options:hover {
background: $deployDisabledButtonHover;
}
&+ #btn-deploy-options:active {
background: $deployDisabledButton;
}
}
img {
margin-right: 8px;
}
}
.deploy-button-group.open {
#btn-deploy-options {
background: $activeButton !important;
}
}
#header .button {
&:active, &.active {
background: $activeButton;
}
&:focus {
outline: none;
}
}
#header li.open .button {
background: $activeButton;
border-color: $activeButton;
}
#header ul.dropdown-menu {
background: $headerMenuBackground;
width: 250px !important;
margin-top: 0;
}
#header ul.dropdown-menu li a {
color: #C7C7C7;
padding: 3px 40px;
}
#header ul.dropdown-menu li a img {
margin-right: 10px;
padding: 4px;
border: 3px solid rgba(0,0,0,0);
}
#header ul.dropdown-menu li a.active img {
border: 3px solid #777677;
}
#header ul.dropdown-menu li a span.menu-label-container {
width: 180px;
vertical-align: top;
display: inline-block;
text-indent: 0px;
}
#header ul.dropdown-menu li a span.menu-label {
font-size: 14px;
display: inline-block;
text-indent: 0px;
}
#header ul.dropdown-menu li a span.menu-sublabel {
color: #aeaeae;
font-size: 13px;
display: inline-block;
text-indent: 0px;
}
#header ul.dropdown-menu > li:hover > a,
#header ul.dropdown-menu > li:focus > a {
background: $headerMenuItemHover !important;
}
#header ul.dropdown-menu li.divider {
background: $headerMenuItemDivider;
border-bottom-color: $headerMenuItemHover;
}
#header ul.dropdown-menu li.disabled a {
color: #666;
}
#header ul.dropdown-menu > li.disabled:hover > a,
#header ul.dropdown-menu > li.disabled:focus > a {
background: none !important;
}
/* Deploy menu customisations */
#header ul#btn-deploy-options-submenu {
width: 300px !important;
}
#header ul#btn-deploy-options-submenu li a span.menu-label {
font-size: 16px;
display: inline-block;
text-indent: 0px;
}
#header ul#btn-deploy-options-submenu li a {
padding: 10px 30px;
color: #fff;
}
#header ul#btn-deploy-options-submenu li a > i.fa {
display: none !important;
}
/* User menu customisations */
#header ul#btn-usermenu-submenu li a#btn-username > .menu-label {
font-size: 16px;
color: #fff;
}

75
editor/sass/jquery.scss Normal file
View File

@@ -0,0 +1,75 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
.ui-widget {
font-size: 14px !important;
font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif !important;
}
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button {
font-size: 14px !important;
font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif !important;
}
/* jQuery Theme overrides */
.ui-tabs .ui-tabs-panel {
padding: 0px;
}
.ui-autocomplete {
max-height: 250px;
overflow-x: hidden;
overflow-y: scroll;
}
.ui-dialog {
border-radius: 1px;
background: #fff;
padding: 0;
@include component-shadow;
}
.ui-dialog .ui-dialog-content {
padding: 25px 25px 10px 25px;
}
.ui-dialog .ui-dialog-title {
width: auto;
}
.ui-dialog .ui-dialog-titlebar {
padding: 10px;
background: #f3f3f3;
border: none;
border-bottom: 1px solid #999;
border-radius: 0;
}
.ui-corner-all {
border-radius: 1px;
}
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {
background: #f3f3f3;
}
.ui-dialog-no-close .ui-dialog-titlebar-close {
display: none;
}
.ui-dialog-buttonset {
text-align: right;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
float: none;
}
.ui-dialog .ui-dialog-buttonpane {
padding: .3em 1em .5em 1em;
}

40
editor/sass/keyboard.scss Normal file
View File

@@ -0,0 +1,40 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
#keyboard-help-dialog {
font-size: 0.9em;
}
.keyboard-shortcuts {
padding: 10px;
}
.keyboard-shortcuts td {
padding: 7px 5px;
margin-bottom: 10px;
white-space: pre;
}
.keyboard-shortcuts td:first-child {
text-align: right;
padding-right: 10px;
}
.help-key {
border: 1px solid #ddd;
padding: 4px;
border-radius: 3px;
background: #f6f6f6;
font-family: Courier, monospace;
box-shadow: #999 1px 1px 1px;
}

33
editor/sass/library.scss Normal file
View File

@@ -0,0 +1,33 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
#node-select-library {
overflow: hidden;
}
#node-select-library ul {
list-style: none;
padding: 0px;
margin: 2px;
}
#node-select-library li {
cursor: pointer;
}
#node-select-library li.list-selected {
background: #eee;
}
#node-select-library li.list-hover {
background: #ffffd0;
}

90
editor/sass/mixins.scss Normal file
View File

@@ -0,0 +1,90 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
@mixin disable-selection {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
@mixin component-border {
border: 1px solid $primary-border-color;
box-sizing: border-box;
}
@mixin workspace-button {
@include disable-selection;
color: $workspace-button-color;
box-sizing: border-box;
display: inline-block;
background: $workspace-button-background;
border: 1px solid $secondary-border-color;
text-align: center;
margin:0;
text-decoration: none;
cursor:pointer;
&.disabled {
cursor: default;
color: $workspace-button-color-disabled;
}
&:not(.disabled):hover {
text-decoration: none;
color: $workspace-button-color-hover;
background: $workspace-button-background-hover;
}
&:not(.disabled):focus {
color: $workspace-button-color-focus;
text-decoration: none;
}
&:not(.disabled):active {
color: $workspace-button-color-active;
background: $workspace-button-background-active;
text-decoration: none;
}
}
@mixin component-footer {
border-top: 1px solid $primary-border-color;
background: #f3f3f3;
text-align: right;
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 25px;
line-height: 23px;
padding: 0 10px;
}
@mixin component-footer-button {
@include workspace-button;
font-size: 11px;
line-height: 17px;
width: 18px;
height: 18px;
&.text-button {
width: auto;
padding: 0 5px;
}
}
@mixin component-shadow {
border: 1px solid $secondary-border-color;
box-shadow: 1px 1px 4px rgba(0,0,0,0.2);
}

View File

@@ -0,0 +1,45 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
#notifications {
z-index: 10000;
width: 500px;
margin-left: -250px;
left: 50%;
position: absolute;
top: 1px;
}
.notification {
box-sizing: border-box;
position: relative;
padding: 14px 18px;
margin-bottom: 4px;
box-shadow: 0 1px 1px 1px rgba(0,0,0, 0.15);
background-color: #fff;
color: #666;
border: 1px solid #325C80;
border-left-width: 16px;
}
.notification-success {
border-color: #4B8400;
}
.notification-warning {
border-color: #D74108;
}
.notification-error {
border-color: #AD1625;
}

212
editor/sass/palette.scss Normal file
View File

@@ -0,0 +1,212 @@
/**
* Copyright 2015 IBM Corp.
*
* 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.
**/
#palette {
position: absolute;
top: 0px;
bottom: 0px;
left:0px;
background: #f3f3f3;
width: 180px;
text-align: center;
@include disable-selection;
@include component-border;
}
.palette-scroll {
display: none;
position: absolute;
top: 35px;
right: 0;
bottom: 25px;
left:0;
padding: 0;
overflow-y: auto;
box-sizing:border-box;
}
.palette-spinner {
padding-top: 40px;
}
#palette-search {
position: absolute;
display: none;
top: 0;
left:0;
right:0;
overflow: hidden;
background: #ffffff;
text-align: center;
height: 35px;
padding: 3px;
border-bottom: 1px solid $primary-border-color;
box-sizing:border-box;
}
#palette-search i {
font-size: 10px;
color: #666;
}
#palette-search i.fa-search {
position: absolute;
pointer-events: none;
left: 12px;
top: 12px;
}
#palette-search i.fa-times {
position: absolute;
right: 7px;
top: 12px;
}
#palette-search-clear {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 20px;
display: none;
}
#palette-search input {
border-radius: 0;
border: none;
width: 100%;
box-shadow: none;
-webkit-box-shadow: none;
padding: 3px 17px 3px 22px;
margin: 0px;
height: 30px;
box-sizing:border-box;
}
#palette-search input:focus {
border: none;
box-shadow: none;
-webkit-box-shadow: none;
}
#palette-footer {
@include component-footer;
}
.palette-button {
@include component-footer-button;
}
.palette-category {
border-bottom: 1px solid #ccc;
}
.palette-content {
background: #fff;
padding: 3px;
}
.palette-header {
background: $palette-header-background;
cursor: pointer;
text-align: left;
padding: 9px;
font-weight: bold;
}
.palette-header i {
margin: 3px 10px 3px 3px;
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
}
.palette-header i.expanded {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
}
.palette-header span {
clear: both;
}
.palette_label {
font-size: 13px;
margin: 4px 0 4px 28px;
line-height: 20px;
overflow: hidden;
text-align: center;
}
.palette_label_right {
margin: 4px 28px 4px 0;
}
.palette_node {
cursor:move;
background: #ddd;
margin: 10px auto;
height: 25px;
border-radius: 5px;
border: 1px solid #999;
background-position: 5% 50%;
background-repeat: no-repeat;
width: 120px;
background-size: contain;
position: relative;
}
.palette_node:hover {
border-color: $node-selected-color;
background-color: #eee;
}
.palette_port {
position: absolute;
top:8px;
left: -5px;
box-sizing: border-box;
-moz-box-sizing: border-box;
background:#d9d9d9;
border-radius: 3px;
width: 10px;
height: 10px;
border: 1px solid #999;
}
.palette_port_output {
left:auto;
right: -6px;
}
.palette_node:hover .palette_port {
border-color: #999;
background-color: #eee;
}
.palette_icon_container {
position: absolute;
text-align: center;
top:0;
bottom:0;
left:0;
width: 30px;
border-right: 1px solid rgba(0,0,0,0.1);
background-color: rgba(0,0,0,0.05);
}
.palette_icon_container_right {
left: auto;
right: 0;
border-right: none;
border-left: 1px solid rgba(0,0,0,0.1);
}
.palette_icon {
display: inline-block;
width: 20px;
height: 100%;
background-position: 50% 50%;
background-size: contain;
background-repeat: no-repeat;
}

53
editor/sass/popover.scss Normal file
View File

@@ -0,0 +1,53 @@
/**
* Copyright 2015 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
.red-ui-popover {
display: none;
position: absolute;
width: 300px;
padding: 10px;
height: auto;
background: #fff;
z-index: 1000;
font-size: 14px;
line-height: 1.4em;
@include component-shadow;
}
.red-ui-popover:after, .red-ui-popover:before {
right: 100%;
top: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.red-ui-popover:after {
border-color: rgba(136, 183, 213, 0);
border-right-color: #fff;
border-width: 10px;
margin-top: -10px;
}
.red-ui-popover:before {
border-color: rgba(194, 225, 245, 0);
border-right-color: $primary-border-color;
border-width: 11px;
margin-top: -11px;
}

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