mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Fix merge conflicts
This commit is contained in:
commit
59ffacb3df
@ -16,7 +16,6 @@ node_js:
|
|||||||
- "7"
|
- "7"
|
||||||
- "6"
|
- "6"
|
||||||
- "4"
|
- "4"
|
||||||
- "0.10"
|
|
||||||
script:
|
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
|
- 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:
|
before_script:
|
||||||
|
31
Gruntfile.js
31
Gruntfile.js
@ -117,7 +117,9 @@ module.exports = function(grunt) {
|
|||||||
"editor/js/ui/common/tabs.js",
|
"editor/js/ui/common/tabs.js",
|
||||||
"editor/js/ui/common/typedInput.js",
|
"editor/js/ui/common/typedInput.js",
|
||||||
"editor/js/ui/utils.js",
|
"editor/js/ui/utils.js",
|
||||||
|
"editor/js/ui/actions.js",
|
||||||
"editor/js/ui/deploy.js",
|
"editor/js/ui/deploy.js",
|
||||||
|
"editor/js/ui/diff.js",
|
||||||
"editor/js/ui/keyboard.js",
|
"editor/js/ui/keyboard.js",
|
||||||
"editor/js/ui/workspaces.js",
|
"editor/js/ui/workspaces.js",
|
||||||
"editor/js/ui/view.js",
|
"editor/js/ui/view.js",
|
||||||
@ -152,6 +154,10 @@ module.exports = function(grunt) {
|
|||||||
"public/vendor/vendor.css": [
|
"public/vendor/vendor.css": [
|
||||||
// TODO: resolve relative resource paths in
|
// TODO: resolve relative resource paths in
|
||||||
// bootstrap/FA/jquery
|
// bootstrap/FA/jquery
|
||||||
|
],
|
||||||
|
"public/vendor/jsonata/jsonata.js": [
|
||||||
|
"node_modules/jsonata/jsonata.js",
|
||||||
|
"editor/vendor/jsonata/formatter.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +166,11 @@ module.exports = function(grunt) {
|
|||||||
build: {
|
build: {
|
||||||
files: {
|
files: {
|
||||||
'public/red/red.min.js': 'public/red/red.js',
|
'public/red/red.min.js': 'public/red/red.js',
|
||||||
'public/red/main.min.js': 'public/red/main.js'
|
'public/red/main.min.js': 'public/red/main.js',
|
||||||
|
'public/vendor/jsonata/jsonata.min.js': 'public/vendor/jsonata/jsonata.js',
|
||||||
|
'public/vendor/ace/mode-jsonata.js': 'editor/vendor/jsonata/mode-jsonata.js',
|
||||||
|
'public/vendor/ace/worker-jsonata.js': 'editor/vendor/jsonata/worker-jsonata.js',
|
||||||
|
'public/vendor/ace/snippets/jsonata.js': 'editor/vendor/jsonata/snippets-jsonata.js'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -186,6 +196,11 @@ module.exports = function(grunt) {
|
|||||||
'red/api/locales/en-US/editor.json',
|
'red/api/locales/en-US/editor.json',
|
||||||
'red/runtime/locales/en-US/runtime.json'
|
'red/runtime/locales/en-US/runtime.json'
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
keymaps: {
|
||||||
|
src: [
|
||||||
|
'editor/js/keymap.json'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
attachCopyright: {
|
attachCopyright: {
|
||||||
@ -222,7 +237,7 @@ module.exports = function(grunt) {
|
|||||||
files: [
|
files: [
|
||||||
'editor/js/**/*.js'
|
'editor/js/**/*.js'
|
||||||
],
|
],
|
||||||
tasks: ['concat','uglify','attachCopyright:js']
|
tasks: ['copy:build','concat','uglify','attachCopyright:js']
|
||||||
},
|
},
|
||||||
sass: {
|
sass: {
|
||||||
files: [
|
files: [
|
||||||
@ -238,6 +253,12 @@ module.exports = function(grunt) {
|
|||||||
],
|
],
|
||||||
tasks: ['jsonlint:messages']
|
tasks: ['jsonlint:messages']
|
||||||
},
|
},
|
||||||
|
keymaps: {
|
||||||
|
files: [
|
||||||
|
'editor/js/keymap.json'
|
||||||
|
],
|
||||||
|
tasks: ['jsonlint:keymaps','copy:build']
|
||||||
|
},
|
||||||
misc: {
|
misc: {
|
||||||
files: [
|
files: [
|
||||||
'CHANGELOG.md'
|
'CHANGELOG.md'
|
||||||
@ -276,6 +297,10 @@ module.exports = function(grunt) {
|
|||||||
src: 'editor/js/main.js',
|
src: 'editor/js/main.js',
|
||||||
dest: 'public/red/main.js'
|
dest: 'public/red/main.js'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
src: 'editor/js/keymap.json',
|
||||||
|
dest: 'public/red/keymap.json'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
cwd: 'editor/images',
|
cwd: 'editor/images',
|
||||||
src: '**',
|
src: '**',
|
||||||
@ -435,7 +460,7 @@ module.exports = function(grunt) {
|
|||||||
|
|
||||||
grunt.registerTask('build',
|
grunt.registerTask('build',
|
||||||
'Builds editor content',
|
'Builds editor content',
|
||||||
['clean:build','concat:build','concat:vendor','copy:build','uglify:build','sass:build','jsonlint:messages','attachCopyright']);
|
['clean:build','jsonlint','concat:build','concat:vendor','copy:build','uglify:build','sass:build','attachCopyright']);
|
||||||
|
|
||||||
grunt.registerTask('dev',
|
grunt.registerTask('dev',
|
||||||
'Developer mode: run node-red, watch for source changes and build/restart',
|
'Developer mode: run node-red, watch for source changes and build/restart',
|
||||||
|
BIN
editor/images/typedInput/expr.png
Normal file
BIN
editor/images/typedInput/expr.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 563 B |
@ -16,6 +16,289 @@
|
|||||||
RED.history = (function() {
|
RED.history = (function() {
|
||||||
var undo_history = [];
|
var undo_history = [];
|
||||||
|
|
||||||
|
function undoEvent(ev) {
|
||||||
|
var i;
|
||||||
|
var len;
|
||||||
|
var node;
|
||||||
|
var subflow;
|
||||||
|
var modifiedTabs = {};
|
||||||
|
if (ev) {
|
||||||
|
if (ev.t == 'multi') {
|
||||||
|
len = ev.events.length;
|
||||||
|
for (i=len-1;i>=0;i--) {
|
||||||
|
undoEvent(ev.events[i]);
|
||||||
|
}
|
||||||
|
} else if (ev.t == 'replace') {
|
||||||
|
RED.nodes.clear();
|
||||||
|
var imported = RED.nodes.import(ev.config);
|
||||||
|
imported[0].forEach(function(n) {
|
||||||
|
if (ev.changed[n.id]) {
|
||||||
|
n.changed = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
RED.nodes.version(ev.rev);
|
||||||
|
} else 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.removedLinks) {
|
||||||
|
for (i=0;i<ev.removedLinks.length;i++) {
|
||||||
|
RED.nodes.addLink(ev.removedLinks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} 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;
|
||||||
|
n.n.changed = n.changed;
|
||||||
|
}
|
||||||
|
// A move could have caused a link splice
|
||||||
|
if (ev.links) {
|
||||||
|
for (i=0;i<ev.links.length;i++) {
|
||||||
|
RED.nodes.removeLink(ev.links[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.removedLinks) {
|
||||||
|
for (i=0;i<ev.removedLinks.length;i++) {
|
||||||
|
RED.nodes.addLink(ev.removedLinks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var outputMap;
|
||||||
|
if (ev.outputMap) {
|
||||||
|
outputMap = {};
|
||||||
|
for (var port in ev.outputMap) {
|
||||||
|
if (ev.outputMap.hasOwnProperty(port) && ev.outputMap[port] !== -1) {
|
||||||
|
outputMap[ev.outputMap[port]] = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RED.editor.updateNodeProperties(ev.node,outputMap);
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ev.t == "reorder") {
|
||||||
|
if (ev.order) {
|
||||||
|
RED.workspaces.order(ev.order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
RED.sidebar.config.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
//TODO: this function is a placeholder until there is a 'save' event that can be listened to
|
//TODO: this function is a placeholder until there is a 'save' event that can be listened to
|
||||||
markAllDirty: function() {
|
markAllDirty: function() {
|
||||||
@ -34,269 +317,7 @@ RED.history = (function() {
|
|||||||
},
|
},
|
||||||
pop: function() {
|
pop: function() {
|
||||||
var ev = undo_history.pop();
|
var ev = undo_history.pop();
|
||||||
var i;
|
undoEvent(ev);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.removedLinks) {
|
|
||||||
for (i=0;i<ev.removedLinks.length;i++) {
|
|
||||||
RED.nodes.addLink(ev.removedLinks[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} 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;
|
|
||||||
n.n.changed = n.changed;
|
|
||||||
}
|
|
||||||
// A move could have caused a link splice
|
|
||||||
if (ev.links) {
|
|
||||||
for (i=0;i<ev.links.length;i++) {
|
|
||||||
RED.nodes.removeLink(ev.links[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.removedLinks) {
|
|
||||||
for (i=0;i<ev.removedLinks.length;i++) {
|
|
||||||
RED.nodes.addLink(ev.removedLinks[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} 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);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var outputMap;
|
|
||||||
if (ev.outputMap) {
|
|
||||||
outputMap = {};
|
|
||||||
for (var port in ev.outputMap) {
|
|
||||||
if (ev.outputMap.hasOwnProperty(port) && ev.outputMap[port] !== -1) {
|
|
||||||
outputMap[ev.outputMap[port]] = port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RED.editor.updateNodeProperties(ev.node,outputMap);
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ev.t == "reorder") {
|
|
||||||
if (ev.order) {
|
|
||||||
RED.workspaces.order(ev.order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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();
|
|
||||||
RED.sidebar.config.refresh();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
peek: function() {
|
peek: function() {
|
||||||
return undo_history[undo_history.length-1];
|
return undo_history[undo_history.length-1];
|
||||||
|
@ -23,7 +23,7 @@ RED.i18n = (function() {
|
|||||||
dynamicLoad: false,
|
dynamicLoad: false,
|
||||||
load:'current',
|
load:'current',
|
||||||
ns: {
|
ns: {
|
||||||
namespaces: ["editor","node-red","infotips"],
|
namespaces: ["editor","node-red","jsonata","infotips"],
|
||||||
defaultNs: "editor"
|
defaultNs: "editor"
|
||||||
},
|
},
|
||||||
fallbackLng: ['en-US'],
|
fallbackLng: ['en-US'],
|
||||||
|
38
editor/js/keymap.json
Normal file
38
editor/js/keymap.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"*": {
|
||||||
|
"ctrl-shift-p":"core:manage-palette",
|
||||||
|
"ctrl-f": "core:search",
|
||||||
|
"ctrl-=": "core:zoom-in",
|
||||||
|
"ctrl--": "core:zoom-out",
|
||||||
|
"ctrl-0": "core:zoom-reset",
|
||||||
|
"ctrl-enter": "core:confirm-edit-tray",
|
||||||
|
"ctrl-escape": "core:cancel-edit-tray",
|
||||||
|
"ctrl-g i": "core:show-info-tab",
|
||||||
|
"ctrl-g d": "core:show-debug-tab",
|
||||||
|
"ctrl-g c": "core:show-config-tab"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"ctrl-e": "core:export",
|
||||||
|
"ctrl-i": "core:import",
|
||||||
|
"backspace": "core:delete",
|
||||||
|
"delete": "core:delete",
|
||||||
|
"enter": "core:edit",
|
||||||
|
"ctrl-c": "core:copy",
|
||||||
|
"ctrl-x": "core:cut",
|
||||||
|
"ctrl-v": "core:paste",
|
||||||
|
"ctrl-z": "core:undo",
|
||||||
|
"ctrl-a": "core:select-all",
|
||||||
|
"shift-?": "core:show-help",
|
||||||
|
"ctrl-space": "core:toggle-sidebar",
|
||||||
|
"up": "core:move-selection-up",
|
||||||
|
"right": "core:move-selection-right",
|
||||||
|
"down": "core:move-selection-down",
|
||||||
|
"left": "core:move-selection-left",
|
||||||
|
"shift-up": "core:step-selection-up",
|
||||||
|
"shift-right": "core:step-selection-right",
|
||||||
|
"shift-down": "core:step-selection-down",
|
||||||
|
"shift-left": "core:step-selection-left",
|
||||||
|
"ctrl-shift-j": "core:show-previous-tab",
|
||||||
|
"ctrl-shift-k": "core:show-next-tab"
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,6 @@
|
|||||||
**/
|
**/
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
|
||||||
function loadNodeList() {
|
function loadNodeList() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
headers: {
|
headers: {
|
||||||
@ -80,6 +79,23 @@
|
|||||||
if (/^#flow\/.+$/.test(currentHash)) {
|
if (/^#flow\/.+$/.test(currentHash)) {
|
||||||
RED.workspaces.show(currentHash.substring(6));
|
RED.workspaces.show(currentHash.substring(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var persistentNotifications = {};
|
||||||
|
RED.comms.subscribe("notification/#",function(topic,msg) {
|
||||||
|
var parts = topic.split("/");
|
||||||
|
var notificationId = parts[1];
|
||||||
|
if (msg.text) {
|
||||||
|
var text = RED._(msg.text,{default:msg.text});
|
||||||
|
if (!persistentNotifications.hasOwnProperty(notificationId)) {
|
||||||
|
persistentNotifications[notificationId] = RED.notify(text,msg.type,msg.timeout === undefined,msg.timeout);
|
||||||
|
} else {
|
||||||
|
persistentNotifications[notificationId].update(text,msg.timeout);
|
||||||
|
}
|
||||||
|
} else if (persistentNotifications.hasOwnProperty(notificationId)) {
|
||||||
|
persistentNotifications[notificationId].close();
|
||||||
|
delete persistentNotifications[notificationId];
|
||||||
|
}
|
||||||
|
});
|
||||||
RED.comms.subscribe("status/#",function(topic,msg) {
|
RED.comms.subscribe("status/#",function(topic,msg) {
|
||||||
var parts = topic.split("/");
|
var parts = topic.split("/");
|
||||||
var node = RED.nodes.node(parts[1]);
|
var node = RED.nodes.node(parts[1]);
|
||||||
@ -98,11 +114,9 @@
|
|||||||
var i,m;
|
var i,m;
|
||||||
var typeList;
|
var typeList;
|
||||||
var info;
|
var info;
|
||||||
|
|
||||||
if (topic == "node/added") {
|
if (topic == "node/added") {
|
||||||
var addedTypes = [];
|
var addedTypes = [];
|
||||||
for (i=0;i<msg.length;i++) {
|
msg.forEach(function(m) {
|
||||||
m = msg[i];
|
|
||||||
var id = m.id;
|
var id = m.id;
|
||||||
RED.nodes.addNodeSet(m);
|
RED.nodes.addNodeSet(m);
|
||||||
addedTypes = addedTypes.concat(m.types);
|
addedTypes = addedTypes.concat(m.types);
|
||||||
@ -111,7 +125,7 @@
|
|||||||
$("body").append(data);
|
$("body").append(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
if (addedTypes.length) {
|
if (addedTypes.length) {
|
||||||
typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>";
|
typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>";
|
||||||
RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
|
RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
|
||||||
@ -172,12 +186,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadEditor() {
|
function loadEditor() {
|
||||||
|
|
||||||
var menuOptions = [];
|
var menuOptions = [];
|
||||||
menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[
|
menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[
|
||||||
{id:"menu-item-view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:RED.view.toggleShowGrid},
|
{id:"menu-item-view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:"core:toggle-show-grid"},
|
||||||
{id:"menu-item-view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:RED.view.toggleSnapGrid},
|
{id:"menu-item-view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"},
|
||||||
{id:"menu-item-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:toggleStatus, selected: true},
|
{id:"menu-item-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:"core:toggle-status", selected: true},
|
||||||
null,
|
null,
|
||||||
// {id:"menu-item-bidi",label:RED._("menu.label.view.textDir"),options:[
|
// {id:"menu-item-bidi",label:RED._("menu.label.view.textDir"),options:[
|
||||||
// {id:"menu-item-bidi-default",toggle:"text-direction",label:RED._("menu.label.view.defaultDir"),selected: true, onselect:function(s) { if(s){RED.text.bidi.setTextDirection("")}}},
|
// {id:"menu-item-bidi-default",toggle:"text-direction",label:RED._("menu.label.view.defaultDir"),selected: true, onselect:function(s) { if(s){RED.text.bidi.setTextDirection("")}}},
|
||||||
@ -186,48 +199,46 @@
|
|||||||
// {id:"menu-item-bidi-auto",toggle:"text-direction",label:RED._("menu.label.view.auto"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("auto")}}}
|
// {id:"menu-item-bidi-auto",toggle:"text-direction",label:RED._("menu.label.view.auto"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("auto")}}}
|
||||||
// ]},
|
// ]},
|
||||||
// null,
|
// null,
|
||||||
{id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:RED.sidebar.toggleSidebar, selected: true}
|
{id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true}
|
||||||
]});
|
]});
|
||||||
menuOptions.push(null);
|
menuOptions.push(null);
|
||||||
menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),options:[
|
menuOptions.push({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-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:import"},
|
||||||
{id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]}
|
{id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]}
|
||||||
]});
|
]});
|
||||||
menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),disabled:true,options:[
|
menuOptions.push({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-clipboard",label:RED._("menu.label.clipboard"),disabled:true,onselect:"core:export"},
|
||||||
{id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:RED.library.export}
|
{id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:"core:library-export"}
|
||||||
]});
|
]});
|
||||||
menuOptions.push(null);
|
menuOptions.push(null);
|
||||||
menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:RED.search.show});
|
menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:"core:search"});
|
||||||
menuOptions.push(null);
|
menuOptions.push(null);
|
||||||
menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:function() {}});
|
menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:"core:show-config-tab"});
|
||||||
menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[
|
menuOptions.push({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-add",label:RED._("menu.label.add"),onselect:"core:add-flow"},
|
||||||
{id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:RED.workspaces.edit},
|
{id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:"core:edit-flow"},
|
||||||
{id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:RED.workspaces.remove}
|
{id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:"core:remove-flow"}
|
||||||
]});
|
]});
|
||||||
menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [
|
menuOptions.push({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-create",label:RED._("menu.label.createSubflow"),onselect:"core:create-subflow"},
|
||||||
{id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:RED.subflow.convertToSubflow},
|
{id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:"core:convert-to-subflow"},
|
||||||
]});
|
]});
|
||||||
menuOptions.push(null);
|
menuOptions.push(null);
|
||||||
if (RED.settings.theme('palette.editable') !== false) {
|
if (RED.settings.theme('palette.editable') !== false) {
|
||||||
RED.palette.editor.init();
|
RED.palette.editor.init();
|
||||||
menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:RED.palette.editor.show});
|
menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"});
|
||||||
menuOptions.push(null);
|
menuOptions.push(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:RED.keyboard.showHelp});
|
menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:"core:show-help"});
|
||||||
menuOptions.push({id:"menu-item-help",
|
menuOptions.push({id:"menu-item-help",
|
||||||
label: RED.settings.theme("menu.menu-item-help.label","Node-RED website"),
|
label: RED.settings.theme("menu.menu-item-help.label","Node-RED website"),
|
||||||
href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")
|
href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")
|
||||||
});
|
});
|
||||||
menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: showAbout });
|
menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: "core:show-about" });
|
||||||
|
|
||||||
RED.menu.init({id:"btn-sidemenu",options: menuOptions});
|
|
||||||
|
|
||||||
RED.user.init();
|
RED.user.init();
|
||||||
|
|
||||||
RED.library.init();
|
RED.library.init();
|
||||||
RED.palette.init();
|
RED.palette.init();
|
||||||
RED.sidebar.init();
|
RED.sidebar.init();
|
||||||
@ -237,15 +248,21 @@
|
|||||||
RED.search.init();
|
RED.search.init();
|
||||||
RED.view.init();
|
RED.view.init();
|
||||||
RED.editor.init();
|
RED.editor.init();
|
||||||
|
RED.keyboard.init();
|
||||||
|
RED.diff.init();
|
||||||
|
|
||||||
|
RED.menu.init({id:"btn-sidemenu",options: menuOptions});
|
||||||
|
|
||||||
RED.deploy.init(RED.settings.theme("deployButton",null));
|
RED.deploy.init(RED.settings.theme("deployButton",null));
|
||||||
|
|
||||||
RED.keyboard.add("workspace", /* ? */ 191,{shift:true},function() {RED.keyboard.showHelp();d3.event.preventDefault();});
|
RED.actions.add("core:show-about", showAbout);
|
||||||
|
|
||||||
RED.comms.connect();
|
RED.comms.connect();
|
||||||
|
|
||||||
$("#main-container").show();
|
$("#main-container").show();
|
||||||
$(".header-toolbar").show();
|
$(".header-toolbar").show();
|
||||||
|
|
||||||
|
|
||||||
loadNodeList();
|
loadNodeList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,21 +24,13 @@ RED.nodes = (function() {
|
|||||||
var workspacesOrder =[];
|
var workspacesOrder =[];
|
||||||
var subflows = {};
|
var subflows = {};
|
||||||
var loadedFlowVersion = null;
|
var loadedFlowVersion = null;
|
||||||
var pending = {
|
|
||||||
deleted: {},
|
var initialLoad;
|
||||||
added: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
var dirty = false;
|
var dirty = false;
|
||||||
|
|
||||||
function setDirty(d) {
|
function setDirty(d) {
|
||||||
dirty = d;
|
dirty = d;
|
||||||
if (!d) {
|
|
||||||
pending = {
|
|
||||||
deleted: {},
|
|
||||||
added: {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
RED.events.emit("nodes:change",{dirty:dirty});
|
RED.events.emit("nodes:change",{dirty:dirty});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,8 +181,6 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
nodes.push(n);
|
nodes.push(n);
|
||||||
}
|
}
|
||||||
delete pending.deleted[n.id];
|
|
||||||
pending.added[n.id] = true;
|
|
||||||
RED.events.emit('nodes:add',n);
|
RED.events.emit('nodes:add',n);
|
||||||
}
|
}
|
||||||
function addLink(l) {
|
function addLink(l) {
|
||||||
@ -256,12 +246,6 @@ RED.nodes = (function() {
|
|||||||
if (node && node._def.onremove) {
|
if (node && node._def.onremove) {
|
||||||
node._def.onremove.call(n);
|
node._def.onremove.call(n);
|
||||||
}
|
}
|
||||||
delete pending.added[id];
|
|
||||||
pending.deleted[id] = true;
|
|
||||||
removedNodes.forEach(function(node) {
|
|
||||||
delete pending.added[node.id];
|
|
||||||
pending.deleted[node.id] = true;
|
|
||||||
});
|
|
||||||
return {links:removedLinks,nodes:removedNodes};
|
return {links:removedLinks,nodes:removedNodes};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,8 +258,6 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
function addWorkspace(ws) {
|
function addWorkspace(ws) {
|
||||||
workspaces[ws.id] = ws;
|
workspaces[ws.id] = ws;
|
||||||
pending.added[ws.id] = true;
|
|
||||||
delete pending.deleted[ws.id];
|
|
||||||
ws._def = {
|
ws._def = {
|
||||||
defaults: {
|
defaults: {
|
||||||
label: {value:""}
|
label: {value:""}
|
||||||
@ -313,8 +295,6 @@ RED.nodes = (function() {
|
|||||||
var result = removeNode(removedNodes[n].id);
|
var result = removeNode(removedNodes[n].id);
|
||||||
removedLinks = removedLinks.concat(result.links);
|
removedLinks = removedLinks.concat(result.links);
|
||||||
}
|
}
|
||||||
pending.deleted[id] = true;
|
|
||||||
delete pending.added[id]
|
|
||||||
return {nodes:removedNodes,links:removedLinks};
|
return {nodes:removedNodes,links:removedLinks};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,8 +324,6 @@ RED.nodes = (function() {
|
|||||||
outputs: sf.out.length
|
outputs: sf.out.length
|
||||||
}
|
}
|
||||||
subflows[sf.id] = sf;
|
subflows[sf.id] = sf;
|
||||||
delete pending.deleted[sf.id];
|
|
||||||
pending.added[sf.id] = true;
|
|
||||||
RED.nodes.registerType("subflow:"+sf.id, {
|
RED.nodes.registerType("subflow:"+sf.id, {
|
||||||
defaults:{name:{value:""}},
|
defaults:{name:{value:""}},
|
||||||
info: sf.info,
|
info: sf.info,
|
||||||
@ -369,8 +347,6 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
function removeSubflow(sf) {
|
function removeSubflow(sf) {
|
||||||
delete subflows[sf.id];
|
delete subflows[sf.id];
|
||||||
delete pending.added[sf.id];
|
|
||||||
pending.deleted[sf.id] = true;
|
|
||||||
registry.removeNodeType("subflow:"+sf.id);
|
registry.removeNodeType("subflow:"+sf.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,6 +673,9 @@ RED.nodes = (function() {
|
|||||||
if (!$.isArray(newNodes)) {
|
if (!$.isArray(newNodes)) {
|
||||||
newNodes = [newNodes];
|
newNodes = [newNodes];
|
||||||
}
|
}
|
||||||
|
if (!initialLoad) {
|
||||||
|
initialLoad = JSON.parse(JSON.stringify(newNodes));
|
||||||
|
}
|
||||||
var unknownTypes = [];
|
var unknownTypes = [];
|
||||||
for (i=0;i<newNodes.length;i++) {
|
for (i=0;i<newNodes.length;i++) {
|
||||||
n = newNodes[i];
|
n = newNodes[i];
|
||||||
@ -722,17 +701,19 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var activeWorkspace = RED.workspaces.active();
|
var activeWorkspace = RED.workspaces.active();
|
||||||
|
//TODO: check the z of the subflow instance and check _that_ if it exists
|
||||||
var activeSubflow = getSubflow(activeWorkspace);
|
var activeSubflow = getSubflow(activeWorkspace);
|
||||||
if (activeSubflow) {
|
for (i=0;i<newNodes.length;i++) {
|
||||||
for (i=0;i<newNodes.length;i++) {
|
var m = /^subflow:(.+)$/.exec(newNodes[i].type);
|
||||||
var m = /^subflow:(.+)$/.exec(newNodes[i].type);
|
if (m) {
|
||||||
if (m) {
|
var subflowId = m[1];
|
||||||
var subflowId = m[1];
|
var parent = getSubflow(newNodes[i].z || activeWorkspace);
|
||||||
|
if (parent) {
|
||||||
var err;
|
var err;
|
||||||
if (subflowId === activeSubflow.id) {
|
if (subflowId === parent.id) {
|
||||||
err = new Error(RED._("notification.errors.cannotAddSubflowToItself"));
|
err = new Error(RED._("notification.errors.cannotAddSubflowToItself"));
|
||||||
}
|
}
|
||||||
if (subflowContains(m[1],activeSubflow.id)) {
|
if (subflowContains(subflowId,parent.id)) {
|
||||||
err = new Error(RED._("notification.errors.cannotAddCircularReference"));
|
err = new Error(RED._("notification.errors.cannotAddCircularReference"));
|
||||||
}
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -1022,8 +1003,9 @@ RED.nodes = (function() {
|
|||||||
for (var w1=0;w1<n.wires.length;w1++) {
|
for (var w1=0;w1<n.wires.length;w1++) {
|
||||||
var wires = (n.wires[w1] instanceof Array)?n.wires[w1]:[n.wires[w1]];
|
var wires = (n.wires[w1] instanceof Array)?n.wires[w1]:[n.wires[w1]];
|
||||||
for (var w2=0;w2<wires.length;w2++) {
|
for (var w2=0;w2<wires.length;w2++) {
|
||||||
if (wires[w2] in node_map) {
|
var existingNode = node_map[wires[w2]] || getNode(wires[w2]);
|
||||||
var link = {source:n,sourcePort:w1,target:node_map[wires[w2]]};
|
if (existingNode) {
|
||||||
|
var link = {source:n,sourcePort:w1,target:existingNode};
|
||||||
addLink(link);
|
addLink(link);
|
||||||
new_links.push(link);
|
new_links.push(link);
|
||||||
}
|
}
|
||||||
@ -1164,6 +1146,38 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
nodes = [];
|
||||||
|
links = [];
|
||||||
|
configNodes = {};
|
||||||
|
workspacesOrder = [];
|
||||||
|
var subflowIds = Object.keys(subflows);
|
||||||
|
subflowIds.forEach(function(id) {
|
||||||
|
RED.subflow.removeSubflow(id)
|
||||||
|
});
|
||||||
|
var workspaceIds = Object.keys(workspaces);
|
||||||
|
workspaceIds.forEach(function(id) {
|
||||||
|
RED.workspaces.remove(workspaces[id]);
|
||||||
|
});
|
||||||
|
defaultWorkspace = null;
|
||||||
|
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
RED.view.redraw(true);
|
||||||
|
RED.palette.refresh();
|
||||||
|
RED.workspaces.refresh();
|
||||||
|
RED.sidebar.config.refresh();
|
||||||
|
|
||||||
|
// var node_defs = {};
|
||||||
|
// var nodes = [];
|
||||||
|
// var configNodes = {};
|
||||||
|
// var links = [];
|
||||||
|
// var defaultWorkspace;
|
||||||
|
// var workspaces = {};
|
||||||
|
// var workspacesOrder =[];
|
||||||
|
// var subflows = {};
|
||||||
|
// var loadedFlowVersion = null;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
registry:registry,
|
registry:registry,
|
||||||
setNodeList: registry.setNodeList,
|
setNodeList: registry.setNodeList,
|
||||||
@ -1180,6 +1194,7 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
add: addNode,
|
add: addNode,
|
||||||
remove: removeNode,
|
remove: removeNode,
|
||||||
|
clear: clear,
|
||||||
|
|
||||||
addLink: addLink,
|
addLink: addLink,
|
||||||
removeLink: removeLink,
|
removeLink: removeLink,
|
||||||
@ -1228,14 +1243,19 @@ RED.nodes = (function() {
|
|||||||
node: getNode,
|
node: getNode,
|
||||||
|
|
||||||
version: flowVersion,
|
version: flowVersion,
|
||||||
|
originalFlow: function(flow) {
|
||||||
|
if (flow === undefined) {
|
||||||
|
return initialLoad;
|
||||||
|
} else {
|
||||||
|
initialLoad = flow;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
filterNodes: filterNodes,
|
filterNodes: filterNodes,
|
||||||
filterLinks: filterLinks,
|
filterLinks: filterLinks,
|
||||||
|
|
||||||
import: importNodes,
|
import: importNodes,
|
||||||
|
|
||||||
pending: function() { return pending },
|
|
||||||
|
|
||||||
getAllFlowNodes: getAllFlowNodes,
|
getAllFlowNodes: getAllFlowNodes,
|
||||||
createExportableNodeSet: createExportableNodeSet,
|
createExportableNodeSet: createExportableNodeSet,
|
||||||
createCompleteNodeSet: createCompleteNodeSet,
|
createCompleteNodeSet: createCompleteNodeSet,
|
||||||
|
35
editor/js/ui/actions.js
Normal file
35
editor/js/ui/actions.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
RED.actions = (function() {
|
||||||
|
var actions = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function addAction(name,handler) {
|
||||||
|
actions[name] = handler;
|
||||||
|
}
|
||||||
|
function removeAction(name) {
|
||||||
|
delete actions[name];
|
||||||
|
}
|
||||||
|
function getAction(name) {
|
||||||
|
return actions[name];
|
||||||
|
}
|
||||||
|
function invokeAction(name) {
|
||||||
|
if (actions.hasOwnProperty(name)) {
|
||||||
|
actions[name]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function listActions() {
|
||||||
|
var result = [];
|
||||||
|
Object.keys(actions).forEach(function(action) {
|
||||||
|
var shortcut = RED.keyboard.getShortcut(action);
|
||||||
|
result.push({id:action,scope:shortcut?shortcut.scope:undefined,key:shortcut?shortcut.key:undefined})
|
||||||
|
})
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
add: addAction,
|
||||||
|
remove: removeAction,
|
||||||
|
get: getAction,
|
||||||
|
invoke: invokeAction,
|
||||||
|
list: listActions
|
||||||
|
}
|
||||||
|
})();
|
@ -257,7 +257,7 @@ RED.clipboard = (function() {
|
|||||||
|
|
||||||
function hideDropTarget() {
|
function hideDropTarget() {
|
||||||
$("#dropTarget").hide();
|
$("#dropTarget").hide();
|
||||||
RED.keyboard.remove(/* ESCAPE */ 27);
|
RED.keyboard.remove("escape");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -274,13 +274,15 @@ RED.clipboard = (function() {
|
|||||||
RED.menu.setDisabled("menu-item-export-library",false);
|
RED.menu.setDisabled("menu-item-export-library",false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
RED.keyboard.add("workspace", /* e */ 69,{ctrl:true},function(){exportNodes();d3.event.preventDefault();});
|
|
||||||
RED.keyboard.add("workspace", /* i */ 73,{ctrl:true},function(){importNodes();d3.event.preventDefault();});
|
RED.actions.add("core:export",exportNodes);
|
||||||
|
RED.actions.add("core:import",importNodes);
|
||||||
|
|
||||||
|
|
||||||
$('#chart').on("dragenter",function(event) {
|
$('#chart').on("dragenter",function(event) {
|
||||||
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
|
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
|
||||||
$("#dropTarget").css({display:'table'});
|
$("#dropTarget").css({display:'table'});
|
||||||
RED.keyboard.add("*", /* ESCAPE */ 27,hideDropTarget);
|
RED.keyboard.add("*", "escape" ,hideDropTarget);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
* - removable : boolean - whether to display delete button on items
|
* - removable : boolean - whether to display delete button on items
|
||||||
* - addItem : function(row,index,itemData) - when an item is added
|
* - addItem : function(row,index,itemData) - when an item is added
|
||||||
* - removeItem : function(itemData) - called when an item is removed
|
* - removeItem : function(itemData) - called when an item is removed
|
||||||
|
* - filter : function(itemData) - called for each item to determine if it should be shown
|
||||||
|
* - sort : function(itemDataA,itemDataB) - called to sort items
|
||||||
|
* - scrollOnAdd : boolean - whether to scroll to newly added items
|
||||||
* methods:
|
* methods:
|
||||||
* - addItem(itemData)
|
* - addItem(itemData)
|
||||||
* - removeItem(itemData)
|
* - removeItem(itemData)
|
||||||
@ -34,6 +37,9 @@
|
|||||||
* - height(height)
|
* - height(height)
|
||||||
* - items()
|
* - items()
|
||||||
* - empty()
|
* - empty()
|
||||||
|
* - filter(filter)
|
||||||
|
* - sort(sort)
|
||||||
|
* - length()
|
||||||
*/
|
*/
|
||||||
$.widget( "nodered.editableList", {
|
$.widget( "nodered.editableList", {
|
||||||
_create: function() {
|
_create: function() {
|
||||||
|
@ -13,9 +13,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RED.menu = (function() {
|
RED.menu = (function() {
|
||||||
|
|
||||||
var menuItems = {};
|
var menuItems = {};
|
||||||
@ -34,17 +31,17 @@ RED.menu = (function() {
|
|||||||
var savedStateActive = isSavedStateActive(opt.id);
|
var savedStateActive = isSavedStateActive(opt.id);
|
||||||
if (savedStateActive) {
|
if (savedStateActive) {
|
||||||
link.addClass("active");
|
link.addClass("active");
|
||||||
opt.onselect.call(opt, true);
|
triggerAction(opt.id,true);
|
||||||
} else if (savedStateActive === false) {
|
} else if (savedStateActive === false) {
|
||||||
link.removeClass("active");
|
link.removeClass("active");
|
||||||
opt.onselect.call(opt, false);
|
triggerAction(opt.id,false);
|
||||||
} else if (opt.hasOwnProperty("selected")) {
|
} else if (opt.hasOwnProperty("selected")) {
|
||||||
if (opt.selected) {
|
if (opt.selected) {
|
||||||
link.addClass("active");
|
link.addClass("active");
|
||||||
} else {
|
} else {
|
||||||
link.removeClass("active");
|
link.removeClass("active");
|
||||||
}
|
}
|
||||||
opt.onselect.call(opt, opt.selected);
|
triggerAction(opt.id,opt.selected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,10 +104,12 @@ RED.menu = (function() {
|
|||||||
setSelected(opt.id, !selected);
|
setSelected(opt.id, !selected);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
opt.onselect.call(opt);
|
triggerAction(opt.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setInitialState();
|
if (opt.toggle) {
|
||||||
|
setInitialState();
|
||||||
|
}
|
||||||
} else if (opt.href) {
|
} else if (opt.href) {
|
||||||
link.attr("target","_blank").attr("href",opt.href);
|
link.attr("target","_blank").attr("href",opt.href);
|
||||||
} else if (!opt.options) {
|
} else if (!opt.options) {
|
||||||
@ -164,6 +163,19 @@ RED.menu = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function triggerAction(id, args) {
|
||||||
|
var opt = menuItems[id];
|
||||||
|
var callback = opt.onselect;
|
||||||
|
if (typeof opt.onselect === 'string') {
|
||||||
|
callback = RED.actions.get(opt.onselect);
|
||||||
|
}
|
||||||
|
if (callback) {
|
||||||
|
callback.call(opt,args);
|
||||||
|
} else {
|
||||||
|
console.log("No callback for",id,opt.onselect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function isSavedStateActive(id) {
|
function isSavedStateActive(id) {
|
||||||
return RED.settings.get("menu-" + id);
|
return RED.settings.get("menu-" + id);
|
||||||
}
|
}
|
||||||
@ -187,11 +199,15 @@ RED.menu = (function() {
|
|||||||
$("#"+id).removeClass("active");
|
$("#"+id).removeClass("active");
|
||||||
}
|
}
|
||||||
if (opt && opt.onselect) {
|
if (opt && opt.onselect) {
|
||||||
opt.onselect.call(opt,state);
|
triggerAction(opt.id,state);
|
||||||
}
|
}
|
||||||
setSavedState(id, state);
|
setSavedState(id, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleSelected(id) {
|
||||||
|
setSelected(id,!isSelected(id));
|
||||||
|
}
|
||||||
|
|
||||||
function setDisabled(id,state) {
|
function setDisabled(id,state) {
|
||||||
if (state) {
|
if (state) {
|
||||||
$("#"+id).parent().addClass("disabled");
|
$("#"+id).parent().addClass("disabled");
|
||||||
@ -231,16 +247,6 @@ RED.menu = (function() {
|
|||||||
var opt = menuItems[id];
|
var opt = menuItems[id];
|
||||||
if (opt) {
|
if (opt) {
|
||||||
opt.onselect = action;
|
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]);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,6 +254,7 @@ RED.menu = (function() {
|
|||||||
init: createMenu,
|
init: createMenu,
|
||||||
setSelected: setSelected,
|
setSelected: setSelected,
|
||||||
isSelected: isSelected,
|
isSelected: isSelected,
|
||||||
|
toggleSelected: toggleSelected,
|
||||||
setDisabled: setDisabled,
|
setDisabled: setDisabled,
|
||||||
addItem: addItem,
|
addItem: addItem,
|
||||||
removeItem: removeItem,
|
removeItem: removeItem,
|
||||||
|
@ -105,6 +105,9 @@ RED.tabs = (function() {
|
|||||||
if (typeof link === "string") {
|
if (typeof link === "string") {
|
||||||
link = ul.find("a[href='#"+link+"']");
|
link = ul.find("a[href='#"+link+"']");
|
||||||
}
|
}
|
||||||
|
if (link.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!link.parent().hasClass("active")) {
|
if (!link.parent().hasClass("active")) {
|
||||||
ul.children().removeClass("active");
|
ul.children().removeClass("active");
|
||||||
ul.children().css({"transition": "width 100ms"});
|
ul.children().css({"transition": "width 100ms"});
|
||||||
@ -126,6 +129,18 @@ RED.tabs = (function() {
|
|||||||
},100);
|
},100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function activatePreviousTab() {
|
||||||
|
var previous = ul.find("li.active").prev();
|
||||||
|
if (previous.length > 0) {
|
||||||
|
activateTab(previous.find("a"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function activateNextTab() {
|
||||||
|
var next = ul.find("li.active").next();
|
||||||
|
if (next.length > 0) {
|
||||||
|
activateTab(next.find("a"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateTabWidths() {
|
function updateTabWidths() {
|
||||||
var tabs = ul.find("li.red-ui-tab");
|
var tabs = ul.find("li.red-ui-tab");
|
||||||
@ -303,6 +318,8 @@ RED.tabs = (function() {
|
|||||||
},
|
},
|
||||||
removeTab: removeTab,
|
removeTab: removeTab,
|
||||||
activateTab: activateTab,
|
activateTab: activateTab,
|
||||||
|
nextTab: activateNextTab,
|
||||||
|
previousTab: activatePreviousTab,
|
||||||
resize: updateTabWidths,
|
resize: updateTabWidths,
|
||||||
count: function() {
|
count: function() {
|
||||||
return ul.find("li.red-ui-tab").size();
|
return ul.find("li.red-ui-tab").size();
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var allOptions = {
|
var allOptions = {
|
||||||
msg: {value:"msg",label:"msg.",validate:validateExpression},
|
msg: {value:"msg",label:"msg.",validate:validateExpression},
|
||||||
flow: {value:"flow",label:"flow.",validate:validateExpression},
|
flow: {value:"flow",label:"flow.",validate:validateExpression},
|
||||||
@ -94,7 +95,22 @@
|
|||||||
bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.png",options:["true","false"]},
|
bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.png",options:["true","false"]},
|
||||||
json: {value:"json",label:"JSON",icon:"red/images/typedInput/json.png", validate: function(v) { try{JSON.parse(v);return true;}catch(e){return false;}}},
|
json: {value:"json",label:"JSON",icon:"red/images/typedInput/json.png", validate: function(v) { try{JSON.parse(v);return true;}catch(e){return false;}}},
|
||||||
re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.png"},
|
re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.png"},
|
||||||
date: {value:"date",label:"timestamp",hasValue:false}
|
date: {value:"date",label:"timestamp",hasValue:false},
|
||||||
|
jsonata: {
|
||||||
|
value: "jsonata",
|
||||||
|
label: "expression",
|
||||||
|
icon: "red/images/typedInput/expr.png",
|
||||||
|
validate: function(v) { try{jsonata(v);return true;}catch(e){return false;}},
|
||||||
|
expand:function() {
|
||||||
|
var that = this;
|
||||||
|
RED.editor.editExpression({
|
||||||
|
value: this.value().replace(/\t/g,"\n"),
|
||||||
|
complete: function(v) {
|
||||||
|
that.value(v.replace(/\n/g,"\t"));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
var nlsd = false;
|
var nlsd = false;
|
||||||
|
|
||||||
@ -188,7 +204,7 @@
|
|||||||
that.uiSelect.addClass('red-ui-typedInput-focus');
|
that.uiSelect.addClass('red-ui-typedInput-focus');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"><i class="fa fa-ellipsis-h"></i></button>').appendTo(this.uiSelect);
|
||||||
|
|
||||||
|
|
||||||
this.type(this.options.default||this.typeList[0].value);
|
this.type(this.options.default||this.typeList[0].value);
|
||||||
@ -322,11 +338,16 @@
|
|||||||
this.uiSelect.width(this.uiWidth);
|
this.uiSelect.width(this.uiWidth);
|
||||||
}
|
}
|
||||||
if (this.typeMap[this.propertyType] && this.typeMap[this.propertyType].hasValue === false) {
|
if (this.typeMap[this.propertyType] && this.typeMap[this.propertyType].hasValue === false) {
|
||||||
this.selectTrigger.css('width',"100%");
|
this.selectTrigger.addClass("red-ui-typedInput-full-width");
|
||||||
} else {
|
} else {
|
||||||
this.selectTrigger.width('auto');
|
this.selectTrigger.removeClass("red-ui-typedInput-full-width");
|
||||||
var labelWidth = this._getLabelWidth(this.selectTrigger);
|
var labelWidth = this._getLabelWidth(this.selectTrigger);
|
||||||
this.elementDiv.css('left',labelWidth+"px");
|
this.elementDiv.css('left',labelWidth+"px");
|
||||||
|
if (this.optionExpandButton.is(":visible")) {
|
||||||
|
this.elementDiv.css('right',"22px");
|
||||||
|
} else {
|
||||||
|
this.elementDiv.css('right','0');
|
||||||
|
}
|
||||||
if (this.optionSelectTrigger) {
|
if (this.optionSelectTrigger) {
|
||||||
this.optionSelectTrigger.css({'left':(labelWidth)+"px",'width':'calc( 100% - '+labelWidth+'px )'});
|
this.optionSelectTrigger.css({'left':(labelWidth)+"px",'width':'calc( 100% - '+labelWidth+'px )'});
|
||||||
}
|
}
|
||||||
@ -396,6 +417,9 @@
|
|||||||
this.selectLabel.text(opt.label);
|
this.selectLabel.text(opt.label);
|
||||||
}
|
}
|
||||||
if (opt.options) {
|
if (opt.options) {
|
||||||
|
if (this.optionExpandButton) {
|
||||||
|
this.optionExpandButton.hide();
|
||||||
|
}
|
||||||
if (this.optionSelectTrigger) {
|
if (this.optionSelectTrigger) {
|
||||||
this.optionSelectTrigger.show();
|
this.optionSelectTrigger.show();
|
||||||
this.elementDiv.hide();
|
this.elementDiv.hide();
|
||||||
@ -429,6 +453,16 @@
|
|||||||
}
|
}
|
||||||
this.elementDiv.show();
|
this.elementDiv.show();
|
||||||
}
|
}
|
||||||
|
if (opt.expand && typeof opt.expand === 'function') {
|
||||||
|
this.optionExpandButton.show();
|
||||||
|
this.optionExpandButton.off('click');
|
||||||
|
this.optionExpandButton.on('click',function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
opt.expand.call(that);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.optionExpandButton.hide();
|
||||||
|
}
|
||||||
this.element.trigger('change',this.propertyType,this.value());
|
this.element.trigger('change',this.propertyType,this.value());
|
||||||
}
|
}
|
||||||
if (image) {
|
if (image) {
|
||||||
|
@ -30,13 +30,13 @@ RED.deploy = (function() {
|
|||||||
|
|
||||||
var deploymentType = "full";
|
var deploymentType = "full";
|
||||||
|
|
||||||
|
var currentDiff = null;
|
||||||
|
|
||||||
function changeDeploymentType(type) {
|
function changeDeploymentType(type) {
|
||||||
deploymentType = type;
|
deploymentType = type;
|
||||||
$("#btn-deploy-icon").attr("src",deploymentTypes[type].img);
|
$("#btn-deploy-icon").attr("src",deploymentTypes[type].img);
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentDiff = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* options:
|
* options:
|
||||||
* type: "default" - Button with drop-down options - no further customisation available
|
* type: "default" - Button with drop-down options - no further customisation available
|
||||||
@ -98,21 +98,33 @@ RED.deploy = (function() {
|
|||||||
height: "auto",
|
height: "auto",
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
text: RED._("deploy.confirm.button.cancel"),
|
text: RED._("common.label.cancel"),
|
||||||
click: function() {
|
click: function() {
|
||||||
$( this ).dialog( "close" );
|
$( this ).dialog( "close" );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// id: "node-dialog-confirm-deploy-review",
|
|
||||||
// text: RED._("deploy.confirm.button.review"),
|
|
||||||
// class: "primary",
|
|
||||||
// click: function() {
|
|
||||||
// showDiff();
|
|
||||||
// $( this ).dialog( "close" );
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
|
id: "node-dialog-confirm-deploy-review",
|
||||||
|
text: RED._("deploy.confirm.button.review"),
|
||||||
|
class: "primary disabled",
|
||||||
|
click: function() {
|
||||||
|
if (!$("#node-dialog-confirm-deploy-review").hasClass('disabled')) {
|
||||||
|
RED.diff.showRemoteDiff();
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "node-dialog-confirm-deploy-merge",
|
||||||
|
text: RED._("deploy.confirm.button.merge"),
|
||||||
|
class: "primary disabled",
|
||||||
|
click: function() {
|
||||||
|
RED.diff.mergeDiff(currentDiff);
|
||||||
|
$( this ).dialog( "close" );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "node-dialog-confirm-deploy-deploy",
|
||||||
text: RED._("deploy.confirm.button.confirm"),
|
text: RED._("deploy.confirm.button.confirm"),
|
||||||
class: "primary",
|
class: "primary",
|
||||||
click: function() {
|
click: function() {
|
||||||
@ -136,10 +148,37 @@ RED.deploy = (function() {
|
|||||||
},
|
},
|
||||||
open: function() {
|
open: function() {
|
||||||
if ($( "#node-dialog-confirm-deploy-type" ).val() === "conflict") {
|
if ($( "#node-dialog-confirm-deploy-type" ).val() === "conflict") {
|
||||||
// $("#node-dialog-confirm-deploy-review").show();
|
$("#node-dialog-confirm-deploy-deploy").hide();
|
||||||
|
$("#node-dialog-confirm-deploy-review").addClass('disabled').show();
|
||||||
|
$("#node-dialog-confirm-deploy-merge").addClass('disabled').show();
|
||||||
|
currentDiff = null;
|
||||||
|
$("#node-dialog-confirm-deploy-conflict-checking").show();
|
||||||
|
$("#node-dialog-confirm-deploy-conflict-auto-merge").hide();
|
||||||
|
$("#node-dialog-confirm-deploy-conflict-manual-merge").hide();
|
||||||
|
|
||||||
|
var now = Date.now();
|
||||||
|
RED.diff.getRemoteDiff(function(diff) {
|
||||||
|
var ellapsed = Math.max(1000 - (Date.now()-now), 0);
|
||||||
|
currentDiff = diff;
|
||||||
|
setTimeout(function() {
|
||||||
|
$("#node-dialog-confirm-deploy-conflict-checking").hide();
|
||||||
|
var d = Object.keys(diff.conflicts);
|
||||||
|
if (d.length === 0) {
|
||||||
|
$("#node-dialog-confirm-deploy-conflict-auto-merge").show();
|
||||||
|
$("#node-dialog-confirm-deploy-merge").removeClass('disabled')
|
||||||
|
} else {
|
||||||
|
$("#node-dialog-confirm-deploy-conflict-manual-merge").show();
|
||||||
|
}
|
||||||
|
$("#node-dialog-confirm-deploy-review").removeClass('disabled')
|
||||||
|
},ellapsed);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
$("#node-dialog-confirm-deploy-hide").parent().hide();
|
$("#node-dialog-confirm-deploy-hide").parent().hide();
|
||||||
} else {
|
} else {
|
||||||
// $("#node-dialog-confirm-deploy-review").hide();
|
$("#node-dialog-confirm-deploy-deploy").show();
|
||||||
|
$("#node-dialog-confirm-deploy-review").hide();
|
||||||
|
$("#node-dialog-confirm-deploy-merge").hide();
|
||||||
$("#node-dialog-confirm-deploy-hide").parent().show();
|
$("#node-dialog-confirm-deploy-hide").parent().show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,198 +196,7 @@ RED.deploy = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// $("#node-dialog-view-diff").dialog({
|
|
||||||
// title: RED._('deploy.confirm.button.review'),
|
|
||||||
// modal: true,
|
|
||||||
// autoOpen: false,
|
|
||||||
// buttons: [
|
|
||||||
// {
|
|
||||||
// text: RED._("deploy.confirm.button.cancel"),
|
|
||||||
// click: function() {
|
|
||||||
// $( this ).dialog( "close" );
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: RED._("deploy.confirm.button.merge"),
|
|
||||||
// class: "primary",
|
|
||||||
// click: function() {
|
|
||||||
// $( this ).dialog( "close" );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ],
|
|
||||||
// open: function() {
|
|
||||||
// $(this).dialog({width:Math.min($(window).width(),900),height:Math.min($(window).height(),600)});
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// $("#node-dialog-view-diff-diff").editableList({
|
|
||||||
// addButton: false,
|
|
||||||
// scrollOnAdd: false,
|
|
||||||
// addItem: function(container,i,object) {
|
|
||||||
// var tab = object.tab.n;
|
|
||||||
// var tabDiv = $('<div>',{class:"node-diff-tab collapsed"}).appendTo(container);
|
|
||||||
//
|
|
||||||
// var titleRow = $('<div>',{class:"node-diff-tab-title"}).appendTo(tabDiv);
|
|
||||||
// titleRow.click(function(evt) {
|
|
||||||
// evt.preventDefault();
|
|
||||||
// titleRow.parent().toggleClass('collapsed');
|
|
||||||
// })
|
|
||||||
// var chevron = $('<i class="fa fa-angle-down node-diff-chevron ">').appendTo(titleRow);
|
|
||||||
// var title = $('<span>').html(tab.label||tab.id).appendTo(titleRow);
|
|
||||||
//
|
|
||||||
// var stats = $('<span>',{class:"node-diff-tab-stats"}).appendTo(titleRow);
|
|
||||||
//
|
|
||||||
// var addedCount = 0;
|
|
||||||
// var deletedCount = 0;
|
|
||||||
// var changedCount = 0;
|
|
||||||
// var conflictedCount = 0;
|
|
||||||
//
|
|
||||||
// object.tab.nodes.forEach(function(node) {
|
|
||||||
// var realNode = RED.nodes.node(node.id);
|
|
||||||
// var hasChanges = false;
|
|
||||||
// if (currentDiff.added[node.id]) {
|
|
||||||
// addedCount++;
|
|
||||||
// hasChanges = true;
|
|
||||||
// }
|
|
||||||
// if (currentDiff.deleted[node.id]) {
|
|
||||||
// deletedCount++;
|
|
||||||
// hasChanges = true;
|
|
||||||
// }
|
|
||||||
// if (currentDiff.changed[node.id]) {
|
|
||||||
// changedCount++;
|
|
||||||
// hasChanges = true;
|
|
||||||
// }
|
|
||||||
// if (currentDiff.conflicted[node.id]) {
|
|
||||||
// conflictedCount++;
|
|
||||||
// hasChanges = true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (hasChanges) {
|
|
||||||
// var def = RED.nodes.getType(node.type)||{};
|
|
||||||
// var div = $("<div>",{class:"node-diff-node-entry collapsed"}).appendTo(tabDiv);
|
|
||||||
// var nodeTitleDiv = $("<div>",{class:"node-diff-node-entry-title"}).appendTo(div);
|
|
||||||
// nodeTitleDiv.click(function(evt) {
|
|
||||||
// evt.preventDefault();
|
|
||||||
// $(this).parent().toggleClass('collapsed');
|
|
||||||
// })
|
|
||||||
// var newNode = currentDiff.newConfig.all[node.id];
|
|
||||||
// var nodePropertiesDiv = $("<div>",{class:"node-diff-node-entry-properties"}).appendTo(div);
|
|
||||||
//
|
|
||||||
// var nodePropertiesTable = $("<table>").appendTo(nodePropertiesDiv);
|
|
||||||
//
|
|
||||||
// if (node.hasOwnProperty('x')) {
|
|
||||||
// if (newNode.x !== node.x || newNode.y !== node.y) {
|
|
||||||
// var currentPosition = node.x+", "+node.y
|
|
||||||
// var newPosition = newNode.x+", "+newNode.y;
|
|
||||||
// $("<tr><td>position</td><td>"+currentPosition+"</td><td>"+newPosition+"</td></tr>").appendTo(nodePropertiesTable);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// var properties = Object.keys(node).filter(function(p) { return p!='z'&&p!='wires'&&p!=='x'&&p!=='y'&&p!=='id'&&p!=='type'&&(!def.defaults||!def.defaults.hasOwnProperty(p))});
|
|
||||||
// if (def.defaults) {
|
|
||||||
// properties = properties.concat(Object.keys(def.defaults));
|
|
||||||
// }
|
|
||||||
// properties.forEach(function(d) {
|
|
||||||
// var localValue = JSON.stringify(node[d]);
|
|
||||||
// var remoteValue = JSON.stringify(newNode[d]);
|
|
||||||
// var originalValue = realNode._config[d];
|
|
||||||
//
|
|
||||||
// if (remoteValue !== originalValue) {
|
|
||||||
// var formattedProperty = formatNodeProperty(node[d]);
|
|
||||||
// var newFormattedProperty = formatNodeProperty(newNode[d]);
|
|
||||||
// if (localValue === originalValue) {
|
|
||||||
// // no conflict change
|
|
||||||
// } else {
|
|
||||||
// // conflicting change
|
|
||||||
// }
|
|
||||||
// $("<tr><td>"+d+'</td><td class="">'+formattedProperty+'</td><td class="node-diff-property-changed">'+newFormattedProperty+"</td></tr>").appendTo(nodePropertiesTable);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// })
|
|
||||||
// var nodeChevron = $('<i class="fa fa-angle-down node-diff-chevron">').appendTo(nodeTitleDiv);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// // var leftColumn = $('<div>',{class:"node-diff-column"}).appendTo(div);
|
|
||||||
// // var rightColumn = $('<div>',{class:"node-diff-column"}).appendTo(div);
|
|
||||||
// // rightColumn.html(" ");
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// var nodeDiv = $("<div>",{class:"node-diff-node-entry-node"}).appendTo(nodeTitleDiv);
|
|
||||||
// var colour = def.color;
|
|
||||||
// var icon_url = "arrow-in.png";
|
|
||||||
// if (node.type === 'tab') {
|
|
||||||
// colour = "#C0DEED";
|
|
||||||
// icon_url = "subflow.png";
|
|
||||||
// } else if (def.category === 'config') {
|
|
||||||
// icon_url = "cog.png";
|
|
||||||
// } else if (node.type === 'unknown') {
|
|
||||||
// icon_url = "alert.png";
|
|
||||||
// } else {
|
|
||||||
// icon_url = def.icon;
|
|
||||||
// }
|
|
||||||
// nodeDiv.css('backgroundColor',colour);
|
|
||||||
//
|
|
||||||
// var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
|
||||||
// $('<div/>',{class:"palette_icon",style:"background-image: url(icons/"+icon_url+")"}).appendTo(iconContainer);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// var contentDiv = $('<div>',{class:"node-diff-node-description"}).appendTo(nodeTitleDiv);
|
|
||||||
//
|
|
||||||
// $('<span>',{class:"node-diff-node-label"}).html(node.label || node.name || node.id).appendTo(contentDiv);
|
|
||||||
// //$('<div>',{class:"red-ui-search-result-node-type"}).html(node.type).appendTo(contentDiv);
|
|
||||||
// //$('<div>',{class:"red-ui-search-result-node-id"}).html(node.id).appendTo(contentDiv);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// var statsInfo = '<span class="node-diff-count">'+object.tab.nodes.length+" nodes"+
|
|
||||||
// (addedCount+deletedCount+changedCount+conflictedCount > 0 ? " : ":"")+
|
|
||||||
// "</span> "+
|
|
||||||
// ((addedCount > 0)?'<span class="node-diff-added">'+addedCount+' added</span> ':'')+
|
|
||||||
// ((deletedCount > 0)?'<span class="node-diff-deleted">'+deletedCount+' deleted</span> ':'')+
|
|
||||||
// ((changedCount > 0)?'<span class="node-diff-changed">'+changedCount+' changed</span> ':'')+
|
|
||||||
// ((conflictedCount > 0)?'<span class="node-diff-conflicted">'+conflictedCount+' conflicts</span>':'');
|
|
||||||
// stats.html(statsInfo);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// //
|
|
||||||
// //
|
|
||||||
// //
|
|
||||||
// // var node = object.node;
|
|
||||||
// // var realNode = RED.nodes.node(node.id);
|
|
||||||
// // var def = RED.nodes.getType(object.node.type)||{};
|
|
||||||
// // var l = "";
|
|
||||||
// // if (def && def.label && realNode) {
|
|
||||||
// // l = def.label;
|
|
||||||
// // try {
|
|
||||||
// // l = (typeof l === "function" ? l.call(realNode) : l);
|
|
||||||
// // } catch(err) {
|
|
||||||
// // console.log("Definition error: "+node.type+".label",err);
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // l = l||node.label||node.name||node.id||"";
|
|
||||||
// // console.log(node);
|
|
||||||
// // var div = $('<div>').appendTo(container);
|
|
||||||
// // div.html(l);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatNodeProperty(prop) {
|
|
||||||
var formattedProperty = prop;
|
|
||||||
if (formattedProperty === null) {
|
|
||||||
formattedProperty = 'null';
|
|
||||||
} else if (formattedProperty === undefined) {
|
|
||||||
formattedProperty = 'undefined';
|
|
||||||
} else if (typeof formattedProperty === 'object') {
|
|
||||||
formattedProperty = JSON.stringify(formattedProperty);
|
|
||||||
}
|
|
||||||
if (/\n/.test(formattedProperty)) {
|
|
||||||
formattedProperty = "<pre>"+formattedProperty+"</pre>"
|
|
||||||
}
|
|
||||||
return formattedProperty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNodeInfo(node) {
|
function getNodeInfo(node) {
|
||||||
@ -393,145 +241,8 @@ RED.deploy = (function() {
|
|||||||
$( "#node-dialog-confirm-deploy-conflict" ).show();
|
$( "#node-dialog-confirm-deploy-conflict" ).show();
|
||||||
$( "#node-dialog-confirm-deploy-type" ).val("conflict");
|
$( "#node-dialog-confirm-deploy-type" ).val("conflict");
|
||||||
$( "#node-dialog-confirm-deploy" ).dialog( "open" );
|
$( "#node-dialog-confirm-deploy" ).dialog( "open" );
|
||||||
|
|
||||||
// $("#node-dialog-confirm-deploy-review").append($('<img src="red/images/spin.svg" style="background: rgba(255,255,255,0.8); margin-top: -16px; margin-left: -8px; height:16px; position: absolute; "/>'));
|
|
||||||
// $("#node-dialog-confirm-deploy-review .ui-button-text").css("opacity",0.4);
|
|
||||||
// $("#node-dialog-confirm-deploy-review").attr("disabled",true).addClass("disabled");
|
|
||||||
// $.ajax({
|
|
||||||
// headers: {
|
|
||||||
// "Accept":"application/json",
|
|
||||||
// },
|
|
||||||
// cache: false,
|
|
||||||
// url: 'flows',
|
|
||||||
// success: function(nodes) {
|
|
||||||
// var newNodes = nodes.flows;
|
|
||||||
// var newRevision = nodes.rev;
|
|
||||||
// generateDiff(currentNodes,newNodes);
|
|
||||||
// $("#node-dialog-confirm-deploy-review").attr("disabled",false).removeClass("disabled");
|
|
||||||
// $("#node-dialog-confirm-deploy-review img").remove();
|
|
||||||
// $("#node-dialog-confirm-deploy-review .ui-button-text").css("opacity",1);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// function parseNodes(nodeList) {
|
|
||||||
// var tabOrder = [];
|
|
||||||
// var tabs = {};
|
|
||||||
// var subflows = {};
|
|
||||||
// var globals = [];
|
|
||||||
// var all = {};
|
|
||||||
//
|
|
||||||
// nodeList.forEach(function(node) {
|
|
||||||
// all[node.id] = node;
|
|
||||||
// if (node.type === 'tab') {
|
|
||||||
// tabOrder.push(node.id);
|
|
||||||
// tabs[node.id] = {n:node,nodes:[]};
|
|
||||||
// } else if (node.type === 'subflow') {
|
|
||||||
// subflows[node.id] = {n:node,nodes:[]};
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// nodeList.forEach(function(node) {
|
|
||||||
// if (node.type !== 'tab' && node.type !== 'subflow') {
|
|
||||||
// if (tabs[node.z]) {
|
|
||||||
// tabs[node.z].nodes.push(node);
|
|
||||||
// } else if (subflows[node.z]) {
|
|
||||||
// subflows[node.z].nodes.push(node);
|
|
||||||
// } else {
|
|
||||||
// globals.push(node);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// return {
|
|
||||||
// all: all,
|
|
||||||
// tabOrder: tabOrder,
|
|
||||||
// tabs: tabs,
|
|
||||||
// subflows: subflows,
|
|
||||||
// globals: globals
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function generateDiff(currentNodes,newNodes) {
|
|
||||||
// var currentConfig = parseNodes(currentNodes);
|
|
||||||
// var newConfig = parseNodes(newNodes);
|
|
||||||
// var pending = RED.nodes.pending();
|
|
||||||
// var added = {};
|
|
||||||
// var deleted = {};
|
|
||||||
// var changed = {};
|
|
||||||
// var conflicted = {};
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Object.keys(currentConfig.all).forEach(function(id) {
|
|
||||||
// var node = RED.nodes.workspace(id)||RED.nodes.subflow(id)||RED.nodes.node(id);
|
|
||||||
// if (!newConfig.all.hasOwnProperty(id)) {
|
|
||||||
// if (!pending.added.hasOwnProperty(id)) {
|
|
||||||
// deleted[id] = true;
|
|
||||||
// conflicted[id] = node.changed;
|
|
||||||
// }
|
|
||||||
// } else if (JSON.stringify(currentConfig.all[id]) !== JSON.stringify(newConfig.all[id])) {
|
|
||||||
// changed[id] = true;
|
|
||||||
// conflicted[id] = node.changed;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// Object.keys(newConfig.all).forEach(function(id) {
|
|
||||||
// if (!currentConfig.all.hasOwnProperty(id) && !pending.deleted.hasOwnProperty(id)) {
|
|
||||||
// added[id] = true;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// // console.log("Added",added);
|
|
||||||
// // console.log("Deleted",deleted);
|
|
||||||
// // console.log("Changed",changed);
|
|
||||||
// // console.log("Conflicted",conflicted);
|
|
||||||
//
|
|
||||||
// var formatString = function(id) {
|
|
||||||
// return conflicted[id]?"!":(added[id]?"+":(deleted[id]?"-":(changed[id]?"~":" ")));
|
|
||||||
// }
|
|
||||||
// newConfig.tabOrder.forEach(function(tabId) {
|
|
||||||
// var tab = newConfig.tabs[tabId];
|
|
||||||
// console.log(formatString(tabId),"Flow:",tab.n.label, "("+tab.n.id+")");
|
|
||||||
// tab.nodes.forEach(function(node) {
|
|
||||||
// console.log(" ",formatString(node.id),node.type,node.name || node.id);
|
|
||||||
// })
|
|
||||||
// if (currentConfig.tabs[tabId]) {
|
|
||||||
// currentConfig.tabs[tabId].nodes.forEach(function(node) {
|
|
||||||
// if (deleted[node.id]) {
|
|
||||||
// console.log(" ",formatString(node.id),node.type,node.name || node.id);
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// currentConfig.tabOrder.forEach(function(tabId) {
|
|
||||||
// if (deleted[tabId]) {
|
|
||||||
// console.log(formatString(tabId),"Flow:",tab.n.label, "("+tab.n.id+")");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// currentDiff = {
|
|
||||||
// currentConfig: currentConfig,
|
|
||||||
// newConfig: newConfig,
|
|
||||||
// added: added,
|
|
||||||
// deleted: deleted,
|
|
||||||
// changed: changed,
|
|
||||||
// conflicted: conflicted
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function showDiff() {
|
|
||||||
// if (currentDiff) {
|
|
||||||
// var list = $("#node-dialog-view-diff-diff");
|
|
||||||
// list.editableList('empty');
|
|
||||||
// var currentConfig = currentDiff.currentConfig;
|
|
||||||
// currentConfig.tabOrder.forEach(function(tabId) {
|
|
||||||
// var tab = currentConfig.tabs[tabId];
|
|
||||||
// list.editableList('addItem',{tab:tab})
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// $("#node-dialog-view-diff").dialog("open");
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
function save(skipValidation,force) {
|
function save(skipValidation,force) {
|
||||||
if (!$("#btn-deploy").hasClass("disabled")) {
|
if (!$("#btn-deploy").hasClass("disabled")) {
|
||||||
if (!skipValidation) {
|
if (!skipValidation) {
|
||||||
@ -624,6 +335,7 @@ RED.deploy = (function() {
|
|||||||
}).done(function(data,textStatus,xhr) {
|
}).done(function(data,textStatus,xhr) {
|
||||||
RED.nodes.dirty(false);
|
RED.nodes.dirty(false);
|
||||||
RED.nodes.version(data.rev);
|
RED.nodes.version(data.rev);
|
||||||
|
RED.nodes.originalFlow(nns);
|
||||||
if (hasUnusedConfig) {
|
if (hasUnusedConfig) {
|
||||||
RED.notify(
|
RED.notify(
|
||||||
'<p>'+RED._("deploy.successfulDeploy")+'</p>'+
|
'<p>'+RED._("deploy.successfulDeploy")+'</p>'+
|
||||||
|
1278
editor/js/ui/diff.js
Normal file
1278
editor/js/ui/diff.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -494,12 +494,13 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getEditStackTitle() {
|
function getEditStackTitle() {
|
||||||
|
|
||||||
var title = '<ul class="editor-tray-breadcrumbs">';
|
var title = '<ul class="editor-tray-breadcrumbs">';
|
||||||
for (var i=0;i<editStack.length;i++) {
|
for (var i=0;i<editStack.length;i++) {
|
||||||
var node = editStack[i];
|
var node = editStack[i];
|
||||||
var label = node.type;
|
var label = node.type;
|
||||||
if (node.type === 'subflow') {
|
if (node.type === '_expression') {
|
||||||
|
label = "Expression editor";
|
||||||
|
} else if (node.type === 'subflow') {
|
||||||
label = RED._("subflow.editSubflow",{name:node.name})
|
label = RED._("subflow.editSubflow",{name:node.name})
|
||||||
} else if (node.type.indexOf("subflow:")===0) {
|
} else if (node.type.indexOf("subflow:")===0) {
|
||||||
var subflow = RED.nodes.subflow(node.type.substring(8));
|
var subflow = RED.nodes.subflow(node.type.substring(8));
|
||||||
@ -526,6 +527,33 @@ RED.editor = (function() {
|
|||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildEditForm(tray,formId,type,ns) {
|
||||||
|
var trayBody = tray.find('.editor-tray-body');
|
||||||
|
var dialogForm = $('<form id="'+formId+'" class="form-horizontal"></form>').appendTo(trayBody);
|
||||||
|
dialogForm.html($("script[data-template-name='"+type+"']").html());
|
||||||
|
ns = ns||"node-red";
|
||||||
|
dialogForm.find('[data-i18n]').each(function() {
|
||||||
|
var current = $(this).attr("data-i18n");
|
||||||
|
var keys = current.split(";");
|
||||||
|
for (var i=0;i<keys.length;i++) {
|
||||||
|
var key = keys[i];
|
||||||
|
if (key.indexOf(":") === -1) {
|
||||||
|
var prefix = "";
|
||||||
|
if (key.indexOf("[")===0) {
|
||||||
|
var parts = key.split("]");
|
||||||
|
prefix = parts[0]+"]";
|
||||||
|
key = parts[1];
|
||||||
|
}
|
||||||
|
keys[i] = prefix+ns+":"+key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$(this).attr("data-i18n",keys.join(";"));
|
||||||
|
});
|
||||||
|
$('<input type="text" style="display: none;" />').prependTo(dialogForm);
|
||||||
|
dialogForm.submit(function(e) { e.preventDefault();});
|
||||||
|
return dialogForm;
|
||||||
|
}
|
||||||
|
|
||||||
function showEditDialog(node) {
|
function showEditDialog(node) {
|
||||||
var editing_node = node;
|
var editing_node = node;
|
||||||
editStack.push(node);
|
editStack.push(node);
|
||||||
@ -763,33 +791,13 @@ RED.editor = (function() {
|
|||||||
if (editing_node) {
|
if (editing_node) {
|
||||||
RED.sidebar.info.refresh(editing_node);
|
RED.sidebar.info.refresh(editing_node);
|
||||||
}
|
}
|
||||||
var trayBody = tray.find('.editor-tray-body');
|
|
||||||
var dialogForm = $('<form id="dialog-form" class="form-horizontal"></form>').appendTo(trayBody);
|
|
||||||
dialogForm.html($("script[data-template-name='"+type+"']").html());
|
|
||||||
var ns;
|
var ns;
|
||||||
if (node._def.set.module === "node-red") {
|
if (node._def.set.module === "node-red") {
|
||||||
ns = "node-red";
|
ns = "node-red";
|
||||||
} else {
|
} else {
|
||||||
ns = node._def.set.id;
|
ns = node._def.set.id;
|
||||||
}
|
}
|
||||||
dialogForm.find('[data-i18n]').each(function() {
|
var dialogForm = buildEditForm(tray,"dialog-form",type,ns);
|
||||||
var current = $(this).attr("data-i18n");
|
|
||||||
var keys = current.split(";");
|
|
||||||
for (var i=0;i<keys.length;i++) {
|
|
||||||
var key = keys[i];
|
|
||||||
if (key.indexOf(":") === -1) {
|
|
||||||
var prefix = "";
|
|
||||||
if (key.indexOf("[")===0) {
|
|
||||||
var parts = key.split("]");
|
|
||||||
prefix = parts[0]+"]";
|
|
||||||
key = parts[1];
|
|
||||||
}
|
|
||||||
keys[i] = prefix+ns+":"+key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$(this).attr("data-i18n",keys.join(";"));
|
|
||||||
});
|
|
||||||
$('<input type="text" style="display: none;" />').prependTo(dialogForm);
|
|
||||||
prepareEditDialog(node,node._def,"node-input");
|
prepareEditDialog(node,node._def,"node-input");
|
||||||
dialogForm.i18n();
|
dialogForm.i18n();
|
||||||
},
|
},
|
||||||
@ -882,7 +890,6 @@ RED.editor = (function() {
|
|||||||
},
|
},
|
||||||
open: function(tray) {
|
open: function(tray) {
|
||||||
var trayHeader = tray.find(".editor-tray-header");
|
var trayHeader = tray.find(".editor-tray-header");
|
||||||
var trayBody = tray.find(".editor-tray-body");
|
|
||||||
var trayFooter = tray.find(".editor-tray-footer");
|
var trayFooter = tray.find(".editor-tray-footer");
|
||||||
|
|
||||||
if (node_def.hasUsers !== false) {
|
if (node_def.hasUsers !== false) {
|
||||||
@ -890,21 +897,8 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
trayFooter.append('<span id="node-config-dialog-scope-container"><span id="node-config-dialog-scope-warning" data-i18n="[title]editor.errors.scopeChange"><i class="fa fa-warning"></i></span><select id="node-config-dialog-scope"></select></span>');
|
trayFooter.append('<span id="node-config-dialog-scope-container"><span id="node-config-dialog-scope-warning" data-i18n="[title]editor.errors.scopeChange"><i class="fa fa-warning"></i></span><select id="node-config-dialog-scope"></select></span>');
|
||||||
|
|
||||||
var dialogForm = $('<form id="node-config-dialog-edit-form" class="form-horizontal"></form>').appendTo(trayBody);
|
var dialogForm = buildEditForm(tray,"node-config-dialog-edit-form",type,ns);
|
||||||
dialogForm.html($("script[data-template-name='"+type+"']").html());
|
|
||||||
dialogForm.find('[data-i18n]').each(function() {
|
|
||||||
var current = $(this).attr("data-i18n");
|
|
||||||
if (current.indexOf(":") === -1) {
|
|
||||||
var prefix = "";
|
|
||||||
if (current.indexOf("[")===0) {
|
|
||||||
var parts = current.split("]");
|
|
||||||
prefix = parts[0]+"]";
|
|
||||||
current = parts[1];
|
|
||||||
}
|
|
||||||
$(this).attr("data-i18n",prefix+ns+":"+current);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$('<input type="text" style="display: none;" />').prependTo(dialogForm);
|
|
||||||
prepareEditDialog(editing_config_node,node_def,"node-config-input");
|
prepareEditDialog(editing_config_node,node_def,"node-config-input");
|
||||||
if (editing_config_node._def.exclusive) {
|
if (editing_config_node._def.exclusive) {
|
||||||
$("#node-config-dialog-scope").hide();
|
$("#node-config-dialog-scope").hide();
|
||||||
@ -1338,30 +1332,7 @@ RED.editor = (function() {
|
|||||||
if (editing_node) {
|
if (editing_node) {
|
||||||
RED.sidebar.info.refresh(editing_node);
|
RED.sidebar.info.refresh(editing_node);
|
||||||
}
|
}
|
||||||
var trayBody = tray.find('.editor-tray-body');
|
var dialogForm = buildEditForm(tray,"dialog-form","subflow-template");
|
||||||
var dialogForm = $('<form id="dialog-form" class="form-horizontal"></form>').appendTo(trayBody);
|
|
||||||
dialogForm.html($("script[data-template-name='subflow-template']").html());
|
|
||||||
var ns = "node-red";
|
|
||||||
dialogForm.find('[data-i18n]').each(function() {
|
|
||||||
var current = $(this).attr("data-i18n");
|
|
||||||
var keys = current.split(";");
|
|
||||||
for (var i=0;i<keys.length;i++) {
|
|
||||||
var key = keys[i];
|
|
||||||
if (key.indexOf(":") === -1) {
|
|
||||||
var prefix = "";
|
|
||||||
if (key.indexOf("[")===0) {
|
|
||||||
var parts = key.split("]");
|
|
||||||
prefix = parts[0]+"]";
|
|
||||||
key = parts[1];
|
|
||||||
}
|
|
||||||
keys[i] = prefix+ns+":"+key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$(this).attr("data-i18n",keys.join(";"));
|
|
||||||
});
|
|
||||||
$('<input type="text" style="display: none;" />').prependTo(dialogForm);
|
|
||||||
|
|
||||||
dialogForm.submit(function(e) { e.preventDefault();});
|
|
||||||
subflowEditor = RED.editor.createEditor({
|
subflowEditor = RED.editor.createEditor({
|
||||||
id: 'subflow-input-info-editor',
|
id: 'subflow-input-info-editor',
|
||||||
mode: 'ace/mode/markdown',
|
mode: 'ace/mode/markdown',
|
||||||
@ -1397,22 +1368,183 @@ RED.editor = (function() {
|
|||||||
RED.tray.show(trayOptions);
|
RED.tray.show(trayOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function editExpression(options) {
|
||||||
|
var value = options.value;
|
||||||
|
var onComplete = options.complete;
|
||||||
|
var type = "_expression"
|
||||||
|
editStack.push({type:type});
|
||||||
|
RED.view.state(RED.state.EDITING);
|
||||||
|
var expressionEditor;
|
||||||
|
|
||||||
|
var trayOptions = {
|
||||||
|
title: getEditStackTitle(),
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
id: "node-dialog-cancel",
|
||||||
|
text: RED._("common.label.cancel"),
|
||||||
|
click: function() {
|
||||||
|
RED.tray.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "node-dialog-ok",
|
||||||
|
text: RED._("common.label.done"),
|
||||||
|
class: "primary",
|
||||||
|
click: function() {
|
||||||
|
$("#node-input-expression-help").html("");
|
||||||
|
onComplete(expressionEditor.getValue());
|
||||||
|
RED.tray.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
resize: function(dimensions) {
|
||||||
|
editTrayWidthCache[type] = dimensions.width;
|
||||||
|
|
||||||
|
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
|
||||||
|
var editorRow = $("#dialog-form>div.node-text-editor-row");
|
||||||
|
var height = $("#dialog-form").height();
|
||||||
|
for (var i=0;i<rows.size();i++) {
|
||||||
|
height -= $(rows[i]).outerHeight(true);
|
||||||
|
}
|
||||||
|
height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom")));
|
||||||
|
$(".node-text-editor").css("height",height+"px");
|
||||||
|
expressionEditor.resize();
|
||||||
|
},
|
||||||
|
open: function(tray) {
|
||||||
|
var trayBody = tray.find('.editor-tray-body');
|
||||||
|
var dialogForm = buildEditForm(tray,'dialog-form','_expression','editor');
|
||||||
|
var funcSelect = $("#node-input-expression-func");
|
||||||
|
Object.keys(jsonata.functions).forEach(function(f) {
|
||||||
|
funcSelect.append($("<option></option>").val(f).text(f));
|
||||||
|
})
|
||||||
|
funcSelect.change(function(e) {
|
||||||
|
var f = $(this).val();
|
||||||
|
var args = RED._('jsonata:'+f+".args",{defaultValue:''});
|
||||||
|
var title = "<h5>"+f+"("+args+")</h5>";
|
||||||
|
var body = marked(RED._('jsonata:'+f+'.desc',{defaultValue:''}));
|
||||||
|
$("#node-input-expression-help").html(title+"<p>"+body+"</p>");
|
||||||
|
|
||||||
|
})
|
||||||
|
expressionEditor = RED.editor.createEditor({
|
||||||
|
id: 'node-input-expression',
|
||||||
|
value: "",
|
||||||
|
mode:"ace/mode/jsonata",
|
||||||
|
options: {
|
||||||
|
enableBasicAutocompletion:true,
|
||||||
|
enableSnippets:true,
|
||||||
|
enableLiveAutocompletion: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var currentToken = null;
|
||||||
|
var currentTokenPos = -1;
|
||||||
|
var currentFunctionMarker = null;
|
||||||
|
|
||||||
|
expressionEditor.getSession().setValue(value||"",-1);
|
||||||
|
expressionEditor.on("changeSelection", function() {
|
||||||
|
var c = expressionEditor.getCursorPosition();
|
||||||
|
var token = expressionEditor.getSession().getTokenAt(c.row,c.column);
|
||||||
|
if (token !== currentToken || (token && /paren/.test(token.type) && c.column !== currentTokenPos)) {
|
||||||
|
currentToken = token;
|
||||||
|
var r,p;
|
||||||
|
var scopedFunction = null;
|
||||||
|
if (token && token.type === 'keyword') {
|
||||||
|
r = c.row;
|
||||||
|
scopedFunction = token;
|
||||||
|
} else {
|
||||||
|
var depth = 0;
|
||||||
|
var next = false;
|
||||||
|
if (token) {
|
||||||
|
if (token.type === 'paren.rparen') {
|
||||||
|
// If this is a block of parens ')))', set
|
||||||
|
// depth to offset against the cursor position
|
||||||
|
// within the block
|
||||||
|
currentTokenPos = c.column;
|
||||||
|
depth = c.column - (token.start + token.value.length);
|
||||||
|
}
|
||||||
|
r = c.row;
|
||||||
|
p = token.index;
|
||||||
|
} else {
|
||||||
|
r = c.row-1;
|
||||||
|
p = -1;
|
||||||
|
}
|
||||||
|
while ( scopedFunction === null && r > -1) {
|
||||||
|
var rowTokens = expressionEditor.getSession().getTokens(r);
|
||||||
|
if (p === -1) {
|
||||||
|
p = rowTokens.length-1;
|
||||||
|
}
|
||||||
|
while (p > -1) {
|
||||||
|
var type = rowTokens[p].type;
|
||||||
|
if (next) {
|
||||||
|
if (type === 'keyword') {
|
||||||
|
scopedFunction = rowTokens[p];
|
||||||
|
// console.log("HIT",scopedFunction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next = false;
|
||||||
|
}
|
||||||
|
if (type === 'paren.lparen') {
|
||||||
|
depth-=rowTokens[p].value.length;
|
||||||
|
} else if (type === 'paren.rparen') {
|
||||||
|
depth+=rowTokens[p].value.length;
|
||||||
|
}
|
||||||
|
if (depth < 0) {
|
||||||
|
next = true;
|
||||||
|
depth = 0;
|
||||||
|
}
|
||||||
|
// console.log(r,p,depth,next,rowTokens[p]);
|
||||||
|
p--;
|
||||||
|
}
|
||||||
|
if (!scopedFunction) {
|
||||||
|
r--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expressionEditor.session.removeMarker(currentFunctionMarker);
|
||||||
|
if (scopedFunction) {
|
||||||
|
//console.log(token,.map(function(t) { return t.type}));
|
||||||
|
funcSelect.val(scopedFunction.value).change();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogForm.i18n();
|
||||||
|
$("#node-input-expression-func-insert").click(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var pos = expressionEditor.getCursorPosition();
|
||||||
|
var f = funcSelect.val();
|
||||||
|
var snippet = jsonata.getFunctionSnippet(f);
|
||||||
|
expressionEditor.insertSnippet(snippet);
|
||||||
|
expressionEditor.focus();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
close: function() {
|
||||||
|
editStack.pop();
|
||||||
|
},
|
||||||
|
show: function() {}
|
||||||
|
}
|
||||||
|
if (editTrayWidthCache.hasOwnProperty(type)) {
|
||||||
|
trayOptions.width = editTrayWidthCache[type];
|
||||||
|
}
|
||||||
|
RED.tray.show(trayOptions);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: function() {
|
init: function() {
|
||||||
RED.tray.init();
|
RED.tray.init();
|
||||||
$(window).on('keydown', function(evt) {
|
RED.actions.add("core:confirm-edit-tray", function() {
|
||||||
if (evt.keyCode === $.ui.keyCode.ESCAPE && (evt.metaKey || evt.ctrlKey)) {
|
$("#node-dialog-ok").click();
|
||||||
$("#node-dialog-cancel").click();
|
$("#node-config-dialog-ok").click();
|
||||||
$("#node-config-dialog-cancel").click();
|
});
|
||||||
} else if (evt.keyCode === $.ui.keyCode.ENTER && (evt.metaKey || evt.ctrlKey)) {
|
RED.actions.add("core:cancel-edit-tray", function() {
|
||||||
$("#node-dialog-ok").click();
|
$("#node-dialog-cancel").click();
|
||||||
$("#node-config-dialog-ok").click();
|
$("#node-config-dialog-cancel").click();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
edit: showEditDialog,
|
edit: showEditDialog,
|
||||||
editConfig: showEditConfigNodeDialog,
|
editConfig: showEditConfigNodeDialog,
|
||||||
editSubflow: showEditSubflowDialog,
|
editSubflow: showEditSubflowDialog,
|
||||||
|
editExpression: editExpression,
|
||||||
validateNode: validateNode,
|
validateNode: validateNode,
|
||||||
updateNodeProperties: updateNodeProperties, // TODO: only exposed for edit-undo
|
updateNodeProperties: updateNodeProperties, // TODO: only exposed for edit-undo
|
||||||
|
|
||||||
@ -1447,7 +1579,6 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
},100);
|
},100);
|
||||||
}
|
}
|
||||||
|
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,98 @@
|
|||||||
RED.keyboard = (function() {
|
RED.keyboard = (function() {
|
||||||
|
|
||||||
var handlers = {};
|
var handlers = {};
|
||||||
|
var partialState;
|
||||||
|
|
||||||
|
var keyMap = {
|
||||||
|
"left":37,
|
||||||
|
"up":38,
|
||||||
|
"right":39,
|
||||||
|
"down":40,
|
||||||
|
"escape":27,
|
||||||
|
"enter": 13,
|
||||||
|
"backspace": 8,
|
||||||
|
"delete": 46,
|
||||||
|
"space": 32,
|
||||||
|
";":186,
|
||||||
|
"=":187,
|
||||||
|
",":188,
|
||||||
|
"-":189,
|
||||||
|
".":190,
|
||||||
|
"/":191,
|
||||||
|
"\\":220,
|
||||||
|
"'":222,
|
||||||
|
"?":191 // <- QWERTY specific
|
||||||
|
}
|
||||||
|
var metaKeyCodes = {
|
||||||
|
16:true,
|
||||||
|
17:true,
|
||||||
|
18: true,
|
||||||
|
91:true,
|
||||||
|
93: true
|
||||||
|
}
|
||||||
|
var actionToKeyMap = {}
|
||||||
|
|
||||||
|
// FF generates some different keycodes because reasons.
|
||||||
|
var firefoxKeyCodeMap = {
|
||||||
|
59:186,
|
||||||
|
61:187,
|
||||||
|
173:189
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
$.getJSON("red/keymap.json",function(data) {
|
||||||
|
for (var scope in data) {
|
||||||
|
if (data.hasOwnProperty(scope)) {
|
||||||
|
var keys = data[scope];
|
||||||
|
for (var key in keys) {
|
||||||
|
if (keys.hasOwnProperty(key)) {
|
||||||
|
addHandler(scope,key,keys[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
RED.actions.add("core:show-help", showKeyboardHelp);
|
||||||
|
|
||||||
|
}
|
||||||
|
function parseKeySpecifier(key) {
|
||||||
|
var parts = key.toLowerCase().split("-");
|
||||||
|
var modifiers = {};
|
||||||
|
var keycode;
|
||||||
|
var blank = 0;
|
||||||
|
for (var i=0;i<parts.length;i++) {
|
||||||
|
switch(parts[i]) {
|
||||||
|
case "ctrl":
|
||||||
|
case "cmd":
|
||||||
|
modifiers.ctrl = true;
|
||||||
|
modifiers.meta = true;
|
||||||
|
break;
|
||||||
|
case "alt":
|
||||||
|
modifiers.alt = true;
|
||||||
|
break;
|
||||||
|
case "shift":
|
||||||
|
modifiers.shift = true;
|
||||||
|
break;
|
||||||
|
case "":
|
||||||
|
blank++;
|
||||||
|
keycode = keyMap["-"];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (keyMap.hasOwnProperty(parts[i])) {
|
||||||
|
keycode = keyMap[parts[i]];
|
||||||
|
} else if (parts[i].length > 1) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
keycode = parts[i].toUpperCase().charCodeAt(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [keycode,modifiers];
|
||||||
|
}
|
||||||
|
|
||||||
function resolveKeyEvent(evt) {
|
function resolveKeyEvent(evt) {
|
||||||
var slot = handlers;
|
var slot = partialState||handlers;
|
||||||
if (evt.ctrlKey || evt.metaKey) {
|
if (evt.ctrlKey || evt.metaKey) {
|
||||||
slot = slot.ctrl;
|
slot = slot.ctrl;
|
||||||
}
|
}
|
||||||
@ -28,9 +117,19 @@ RED.keyboard = (function() {
|
|||||||
if (slot && evt.altKey) {
|
if (slot && evt.altKey) {
|
||||||
slot = slot.alt;
|
slot = slot.alt;
|
||||||
}
|
}
|
||||||
if (slot && slot[evt.keyCode]) {
|
var keyCode = firefoxKeyCodeMap[evt.keyCode] || evt.keyCode;
|
||||||
var handler = slot[evt.keyCode];
|
if (slot && slot[keyCode]) {
|
||||||
if (handler.scope && handler.scope !== "*") {
|
var handler = slot[keyCode];
|
||||||
|
if (!handler.scope) {
|
||||||
|
if (partialState) {
|
||||||
|
partialState = null;
|
||||||
|
return resolveKeyEvent(evt);
|
||||||
|
} else {
|
||||||
|
partialState = handler;
|
||||||
|
evt.preventDefault();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (handler.scope && handler.scope !== "*") {
|
||||||
var target = evt.target;
|
var target = evt.target;
|
||||||
while (target.nodeName !== 'BODY' && target.id !== handler.scope) {
|
while (target.nodeName !== 'BODY' && target.id !== handler.scope) {
|
||||||
target = target.parentElement;
|
target = target.parentElement;
|
||||||
@ -39,66 +138,124 @@ RED.keyboard = (function() {
|
|||||||
handler = null;
|
handler = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
partialState = null;
|
||||||
return handler;
|
return handler;
|
||||||
|
} else if (partialState) {
|
||||||
|
partialState = null;
|
||||||
|
return resolveKeyEvent(evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d3.select(window).on("keydown",function() {
|
d3.select(window).on("keydown",function() {
|
||||||
|
if (metaKeyCodes[d3.event.keyCode]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var handler = resolveKeyEvent(d3.event);
|
var handler = resolveKeyEvent(d3.event);
|
||||||
if (handler && handler.ondown) {
|
if (handler && handler.ondown) {
|
||||||
handler.ondown();
|
if (typeof handler.ondown === "string") {
|
||||||
}
|
RED.actions.invoke(handler.ondown);
|
||||||
});
|
} else {
|
||||||
d3.select(window).on("keyup",function() {
|
handler.ondown();
|
||||||
var handler = resolveKeyEvent(d3.event);
|
}
|
||||||
if (handler && handler.onup) {
|
d3.event.preventDefault();
|
||||||
handler.onup();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function addHandler(scope,key,modifiers,ondown,onup) {
|
function addHandler(scope,key,modifiers,ondown) {
|
||||||
var mod = modifiers;
|
var mod = modifiers;
|
||||||
var cbdown = ondown;
|
var cbdown = ondown;
|
||||||
var cbup = onup;
|
if (typeof modifiers == "function" || typeof modifiers === "string") {
|
||||||
if (typeof modifiers == "function") {
|
|
||||||
mod = {};
|
mod = {};
|
||||||
cbdown = modifiers;
|
cbdown = modifiers;
|
||||||
cbup = ondown;
|
}
|
||||||
|
var keys = [];
|
||||||
|
var i=0;
|
||||||
|
if (typeof key === 'string') {
|
||||||
|
if (typeof cbdown === 'string') {
|
||||||
|
actionToKeyMap[cbdown] = {scope:scope,key:key};
|
||||||
|
}
|
||||||
|
var parts = key.split(" ");
|
||||||
|
for (i=0;i<parts.length;i++) {
|
||||||
|
var parsedKey = parseKeySpecifier(parts[i]);
|
||||||
|
if (parsedKey) {
|
||||||
|
keys.push(parsedKey);
|
||||||
|
} else {
|
||||||
|
console.log("Unrecognised key specifier:",key)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keys.push([key,mod])
|
||||||
}
|
}
|
||||||
var slot = handlers;
|
var slot = handlers;
|
||||||
if (mod.ctrl) {
|
for (i=0;i<keys.length;i++) {
|
||||||
slot.ctrl = slot.ctrl||{};
|
key = keys[i][0];
|
||||||
slot = slot.ctrl;
|
mod = keys[i][1];
|
||||||
|
if (mod.ctrl) {
|
||||||
|
slot.ctrl = slot.ctrl||{};
|
||||||
|
slot = slot.ctrl;
|
||||||
|
}
|
||||||
|
if (mod.shift) {
|
||||||
|
slot.shift = slot.shift||{};
|
||||||
|
slot = slot.shift;
|
||||||
|
}
|
||||||
|
if (mod.alt) {
|
||||||
|
slot.alt = slot.alt||{};
|
||||||
|
slot = slot.alt;
|
||||||
|
}
|
||||||
|
slot[key] = slot[key] || {};
|
||||||
|
slot = slot[key];
|
||||||
|
//slot[key] = {scope: scope, ondown:cbdown};
|
||||||
}
|
}
|
||||||
if (mod.shift) {
|
slot.scope = scope;
|
||||||
slot.shift = slot.shift||{};
|
slot.ondown = cbdown;
|
||||||
slot = slot.shift;
|
|
||||||
}
|
|
||||||
if (mod.alt) {
|
|
||||||
slot.alt = slot.alt||{};
|
|
||||||
slot = slot.alt;
|
|
||||||
}
|
|
||||||
slot[key] = {scope: scope, ondown:cbdown, onup:cbup};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeHandler(key,modifiers) {
|
function removeHandler(key,modifiers) {
|
||||||
var mod = modifiers || {};
|
var mod = modifiers || {};
|
||||||
|
var keys = [];
|
||||||
|
var i=0;
|
||||||
|
if (typeof key === 'string') {
|
||||||
|
delete actionToKeyMap[key];
|
||||||
|
var parts = key.split(" ");
|
||||||
|
for (i=0;i<parts.length;i++) {
|
||||||
|
var parsedKey = parseKeySpecifier(parts[i]);
|
||||||
|
if (parsedKey) {
|
||||||
|
keys.push(parsedKey);
|
||||||
|
} else {
|
||||||
|
console.log("Unrecognised key specifier:",key)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keys.push([key,mod])
|
||||||
|
}
|
||||||
var slot = handlers;
|
var slot = handlers;
|
||||||
if (mod.ctrl) {
|
for (i=0;i<keys.length;i++) {
|
||||||
slot = slot.ctrl;
|
key = keys[i][0];
|
||||||
}
|
mod = keys[i][1];
|
||||||
if (slot && mod.shift) {
|
if (mod.ctrl) {
|
||||||
slot = slot.shift;
|
slot = slot.ctrl;
|
||||||
}
|
}
|
||||||
if (slot && mod.alt) {
|
if (slot && mod.shift) {
|
||||||
slot = slot.alt;
|
slot = slot.shift;
|
||||||
}
|
}
|
||||||
if (slot) {
|
if (slot && mod.alt) {
|
||||||
delete slot[key];
|
slot = slot.alt;
|
||||||
|
}
|
||||||
|
if (!slot[key]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
slot = slot[key];
|
||||||
}
|
}
|
||||||
|
delete slot.scope;
|
||||||
|
delete slot.ondown;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dialog = null;
|
var dialog = null;
|
||||||
|
|
||||||
|
var isMac = /Mac/i.test(window.navigator.platform);
|
||||||
|
var cmdCtrlKey = '<span class="help-key">'+(isMac?'⌘':'Ctrl')+'</span>';
|
||||||
|
|
||||||
function showKeyboardHelp() {
|
function showKeyboardHelp() {
|
||||||
if (!RED.settings.theme("menu.menu-item-keyboard-shortcuts",true)) {
|
if (!RED.settings.theme("menu.menu-item-keyboard-shortcuts",true)) {
|
||||||
return;
|
return;
|
||||||
@ -107,30 +264,30 @@ RED.keyboard = (function() {
|
|||||||
dialog = $('<div id="keyboard-help-dialog" class="hide">'+
|
dialog = $('<div id="keyboard-help-dialog" class="hide">'+
|
||||||
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
|
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
|
||||||
'<table class="keyboard-shortcuts">'+
|
'<table class="keyboard-shortcuts">'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">a</span></td><td>'+RED._("keyboard.selectAll")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <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">Shift</span> + <span class="help-key">Click</span></td><td>'+RED._("keyboard.selectAllConnected")+'</td></tr>'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">Click</span></td><td>'+RED._("keyboard.addRemoveNode")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">Click</span></td><td>'+RED._("keyboard.addRemoveNode")+'</td></tr>'+
|
||||||
'<tr><td> </td><td></td></tr>'+
|
'<tr><td> </td><td></td></tr>'+
|
||||||
'<tr><td><span class="help-key">Enter</span></td><td>'+RED._("keyboard.editSelected")+'</td></tr>'+
|
'<tr><td><span class="help-key">Enter</span></td><td>'+RED._("keyboard.editSelected")+'</td></tr>'+
|
||||||
'<tr><td><span class="help-key">Delete</span> / <span class="help-key">Backspace</span></td><td>'+RED._("keyboard.deleteSelected")+'</td></tr>'+
|
'<tr><td><span class="help-key">Delete</span> / <span class="help-key">Backspace</span></td><td>'+RED._("keyboard.deleteSelected")+'</td></tr>'+
|
||||||
'<tr><td> </td><td></td></tr>'+
|
'<tr><td> </td><td></td></tr>'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">i</span></td><td>'+RED._("keyboard.importNode")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">i</span></td><td>'+RED._("keyboard.importNode")+'</td></tr>'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">e</span></td><td>'+RED._("keyboard.exportNode")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">e</span></td><td>'+RED._("keyboard.exportNode")+'</td></tr>'+
|
||||||
'</table>'+
|
'</table>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
|
'<div style="vertical-align: top;display:inline-block; box-sizing: border-box; width:50%; padding: 10px;">'+
|
||||||
'<table class="keyboard-shortcuts">'+
|
'<table class="keyboard-shortcuts">'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">Space</span></td><td>'+RED._("keyboard.toggleSidebar")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">Space</span></td><td>'+RED._("keyboard.toggleSidebar")+'</td></tr>'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">.</span></td><td>'+RED._("keyboard.searchBox")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">f</span></td><td>'+RED._("keyboard.searchBox")+'</td></tr>'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">Shift</span> + <span class="help-key">p</span></td><td>'+RED._("keyboard.managePalette")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">Shift</span> + <span class="help-key">p</span></td><td>'+RED._("keyboard.managePalette")+'</td></tr>'+
|
||||||
'<tr><td> </td><td></td></tr>'+
|
'<tr><td> </td><td></td></tr>'+
|
||||||
'<tr><td><span class="help-key">←</span> <span class="help-key">↑</span> <span class="help-key">→</span> <span class="help-key">↓</span></td><td>'+RED._("keyboard.nudgeNode")+'</td></tr>'+
|
'<tr><td><span class="help-key">←</span> <span class="help-key">↑</span> <span class="help-key">→</span> <span class="help-key">↓</span></td><td>'+RED._("keyboard.nudgeNode")+'</td></tr>'+
|
||||||
'<tr><td><span class="help-key">Shift</span> + <span class="help-key">←</span> <span class="help-key">↑</span> <span class="help-key">→</span> <span class="help-key">↓</span></td><td>'+RED._("keyboard.moveNode")+'</td></tr>'+
|
'<tr><td><span class="help-key">Shift</span> + <span class="help-key">←</span> <span class="help-key">↑</span> <span class="help-key">→</span> <span class="help-key">↓</span></td><td>'+RED._("keyboard.moveNode")+'</td></tr>'+
|
||||||
'<tr><td> </td><td></td></tr>'+
|
'<tr><td> </td><td></td></tr>'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">c</span></td><td>'+RED._("keyboard.copyNode")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">c</span></td><td>'+RED._("keyboard.copyNode")+'</td></tr>'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">x</span></td><td>'+RED._("keyboard.cutNode")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">x</span></td><td>'+RED._("keyboard.cutNode")+'</td></tr>'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">v</span></td><td>'+RED._("keyboard.pasteNode")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">v</span></td><td>'+RED._("keyboard.pasteNode")+'</td></tr>'+
|
||||||
'<tr><td><span class="help-key">Ctrl/⌘</span> + <span class="help-key">z</span></td><td>'+RED._("keyboard.undoChange")+'</td></tr>'+
|
'<tr><td>'+cmdCtrlKey+' + <span class="help-key">z</span></td><td>'+RED._("keyboard.undoChange")+'</td></tr>'+
|
||||||
'</table>'+
|
'</table>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'</div>')
|
'</div>')
|
||||||
@ -148,9 +305,12 @@ RED.keyboard = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
init: init,
|
||||||
add: addHandler,
|
add: addHandler,
|
||||||
remove: removeHandler,
|
remove: removeHandler,
|
||||||
showHelp: showKeyboardHelp
|
getShortcut: function(actionName) {
|
||||||
|
return actionToKeyMap[actionName];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -410,6 +410,9 @@ RED.library = (function() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
init: function() {
|
init: function() {
|
||||||
|
|
||||||
|
RED.actions.add("core:library-export",exportFlow);
|
||||||
|
|
||||||
RED.events.on("view:selection-changed",function(selection) {
|
RED.events.on("view:selection-changed",function(selection) {
|
||||||
if (!selection.nodes) {
|
if (!selection.nodes) {
|
||||||
RED.menu.setDisabled("menu-item-export",true);
|
RED.menu.setDisabled("menu-item-export",true);
|
||||||
|
@ -51,8 +51,14 @@ RED.notify = (function() {
|
|||||||
|
|
||||||
n.update = (function() {
|
n.update = (function() {
|
||||||
var nn = n;
|
var nn = n;
|
||||||
return function(msg) {
|
return function(msg,timeout) {
|
||||||
nn.innerHTML = msg;
|
nn.innerHTML = msg;
|
||||||
|
if (timeout !== undefined && timeout > 0) {
|
||||||
|
window.clearTimeout(nn.timeoutid);
|
||||||
|
nn.timeoutid = window.setTimeout(nn.close,timeout);
|
||||||
|
} else {
|
||||||
|
window.clearTimeout(nn.timeoutid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -302,10 +302,10 @@ RED.palette.editor = (function() {
|
|||||||
filterInput.focus();
|
filterInput.focus();
|
||||||
},250);
|
},250);
|
||||||
RED.events.emit("palette-editor:open");
|
RED.events.emit("palette-editor:open");
|
||||||
RED.keyboard.add("*",/* ESCAPE */ 27,function(){hidePaletteEditor();d3.event.preventDefault();});
|
RED.keyboard.add("*","escape",function(){hidePaletteEditor()});
|
||||||
}
|
}
|
||||||
function hidePaletteEditor() {
|
function hidePaletteEditor() {
|
||||||
RED.keyboard.remove("*");
|
RED.keyboard.remove("escape");
|
||||||
$("#main-container").removeClass("palette-expanded");
|
$("#main-container").removeClass("palette-expanded");
|
||||||
$("#header-shade").hide();
|
$("#header-shade").hide();
|
||||||
$("#editor-shade").hide();
|
$("#editor-shade").hide();
|
||||||
@ -425,7 +425,7 @@ RED.palette.editor = (function() {
|
|||||||
RED.events.on("type-search:open",function() { disabled = true; });
|
RED.events.on("type-search:open",function() { disabled = true; });
|
||||||
RED.events.on("type-search:close",function() { disabled = false; });
|
RED.events.on("type-search:close",function() { disabled = false; });
|
||||||
|
|
||||||
RED.keyboard.add("*", /* p */ 80,{shift:true,ctrl:true},function() {RED.palette.editor.show();d3.event.preventDefault();});
|
RED.actions.add("core:manage-palette",RED.palette.editor.show);
|
||||||
|
|
||||||
editorTabs = RED.tabs.create({
|
editorTabs = RED.tabs.create({
|
||||||
id:"palette-editor-tabs",
|
id:"palette-editor-tabs",
|
||||||
@ -754,7 +754,9 @@ RED.palette.editor = (function() {
|
|||||||
refreshNodeModule(ns.module);
|
refreshNodeModule(ns.module);
|
||||||
for (var i=0;i<filteredList.length;i++) {
|
for (var i=0;i<filteredList.length;i++) {
|
||||||
if (filteredList[i].info.id === ns.module) {
|
if (filteredList[i].info.id === ns.module) {
|
||||||
filteredList[i].elements.installButton.hide();
|
var installButton = filteredList[i].elements.installButton;
|
||||||
|
installButton.addClass('disabled');
|
||||||
|
installButton.html(RED._('palette.editor.installed'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -768,7 +770,9 @@ RED.palette.editor = (function() {
|
|||||||
delete nodeEntries[ns.module];
|
delete nodeEntries[ns.module];
|
||||||
for (var i=0;i<filteredList.length;i++) {
|
for (var i=0;i<filteredList.length;i++) {
|
||||||
if (filteredList[i].info.id === ns.module) {
|
if (filteredList[i].info.id === ns.module) {
|
||||||
filteredList[i].elements.installButton.show();
|
var installButton = filteredList[i].elements.installButton;
|
||||||
|
installButton.removeClass('disabled');
|
||||||
|
installButton.html(RED._('palette.editor.install'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,9 @@ RED.search = (function() {
|
|||||||
|
|
||||||
|
|
||||||
var properties = ['id','type','name','label','info'];
|
var properties = ['id','type','name','label','info'];
|
||||||
|
if (n._def && n._def.defaults) {
|
||||||
|
properties = properties.concat(Object.keys(n._def.defaults));
|
||||||
|
}
|
||||||
for (var i=0;i<properties.length;i++) {
|
for (var i=0;i<properties.length;i++) {
|
||||||
if (n.hasOwnProperty(properties[i])) {
|
if (n.hasOwnProperty(properties[i])) {
|
||||||
var v = n[properties[i]];
|
var v = n[properties[i]];
|
||||||
@ -238,8 +241,11 @@ RED.search = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
|
if (disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
RED.keyboard.add("*",/* ESCAPE */ 27,function(){hide();d3.event.preventDefault();});
|
RED.keyboard.add("*","escape",function(){hide()});
|
||||||
$("#header-shade").show();
|
$("#header-shade").show();
|
||||||
$("#editor-shade").show();
|
$("#editor-shade").show();
|
||||||
$("#palette-shade").show();
|
$("#palette-shade").show();
|
||||||
@ -257,7 +263,7 @@ RED.search = (function() {
|
|||||||
}
|
}
|
||||||
function hide() {
|
function hide() {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
RED.keyboard.remove(/* ESCAPE */ 27);
|
RED.keyboard.remove("escape");
|
||||||
visible = false;
|
visible = false;
|
||||||
$("#header-shade").hide();
|
$("#header-shade").hide();
|
||||||
$("#editor-shade").hide();
|
$("#editor-shade").hide();
|
||||||
@ -274,7 +280,8 @@ RED.search = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
RED.keyboard.add("*",/* . */ 190,{ctrl:true},function(){if (!disabled) { show(); } d3.event.preventDefault();});
|
RED.actions.add("core:search",show);
|
||||||
|
|
||||||
RED.events.on("editor:open",function() { disabled = true; });
|
RED.events.on("editor:open",function() { disabled = true; });
|
||||||
RED.events.on("editor:close",function() { disabled = false; });
|
RED.events.on("editor:close",function() { disabled = false; });
|
||||||
RED.events.on("palette-editor:open",function() { disabled = true; });
|
RED.events.on("palette-editor:open",function() { disabled = true; });
|
||||||
|
@ -202,12 +202,18 @@ RED.sidebar = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init () {
|
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();});
|
RED.actions.add("core:toggle-sidebar",function(state){
|
||||||
|
if (state === undefined) {
|
||||||
|
RED.menu.toggleSelected("menu-item-sidebar");
|
||||||
|
} else {
|
||||||
|
toggleSidebar(state);
|
||||||
|
}
|
||||||
|
});
|
||||||
showSidebar();
|
showSidebar();
|
||||||
RED.sidebar.info.init();
|
RED.sidebar.info.init();
|
||||||
RED.sidebar.config.init();
|
RED.sidebar.config.init();
|
||||||
// hide info bar at start if screen rather narrow...
|
// hide info bar at start if screen rather narrow...
|
||||||
if ($(window).width() < 600) { toggleSidebar(); }
|
if ($(window).width() < 600) { RED.menu.setSelected("menu-item-sidebar",false); }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -306,50 +306,13 @@ RED.subflow = (function() {
|
|||||||
|
|
||||||
$("#workspace-subflow-delete").click(function(event) {
|
$("#workspace-subflow-delete").click(function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var removedNodes = [];
|
|
||||||
var removedLinks = [];
|
|
||||||
var startDirty = RED.nodes.dirty();
|
var startDirty = RED.nodes.dirty();
|
||||||
|
var historyEvent = removeSubflow(RED.workspaces.active());
|
||||||
|
historyEvent.t = 'delete';
|
||||||
|
historyEvent.dirty = startDirty;
|
||||||
|
|
||||||
var activeSubflow = getSubflow();
|
RED.history.push(historyEvent);
|
||||||
|
|
||||||
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);
|
refreshToolbar(activeSubflow);
|
||||||
@ -362,7 +325,48 @@ RED.subflow = (function() {
|
|||||||
$("#chart").css({"margin-top": "0"});
|
$("#chart").css({"margin-top": "0"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeSubflow(id) {
|
||||||
|
var removedNodes = [];
|
||||||
|
var removedLinks = [];
|
||||||
|
|
||||||
|
var activeSubflow = RED.nodes.subflow(id);
|
||||||
|
|
||||||
|
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.workspaces.remove(activeSubflow);
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
RED.view.redraw();
|
||||||
|
|
||||||
|
return {
|
||||||
|
nodes:removedNodes,
|
||||||
|
links:removedLinks,
|
||||||
|
subflow: {
|
||||||
|
subflow: activeSubflow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
function init() {
|
function init() {
|
||||||
RED.events.on("workspace:change",function(event) {
|
RED.events.on("workspace:change",function(event) {
|
||||||
var activeSubflow = RED.nodes.subflow(event.workspace);
|
var activeSubflow = RED.nodes.subflow(event.workspace);
|
||||||
@ -380,6 +384,8 @@ RED.subflow = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RED.actions.add("core:create-subflow",createSubflow);
|
||||||
|
RED.actions.add("core:convert-to-subflow",convertToSubflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSubflow() {
|
function createSubflow() {
|
||||||
@ -617,6 +623,7 @@ RED.subflow = (function() {
|
|||||||
init: init,
|
init: init,
|
||||||
createSubflow: createSubflow,
|
createSubflow: createSubflow,
|
||||||
convertToSubflow: convertToSubflow,
|
convertToSubflow: convertToSubflow,
|
||||||
|
removeSubflow: removeSubflow,
|
||||||
refresh: refresh,
|
refresh: refresh,
|
||||||
removeInput: removeSubflowInput,
|
removeInput: removeSubflowInput,
|
||||||
removeOutput: removeSubflowOutput
|
removeOutput: removeSubflowOutput
|
||||||
|
@ -236,10 +236,7 @@ RED.sidebar.config = (function() {
|
|||||||
visible: false,
|
visible: false,
|
||||||
onchange: function() { refreshConfigNodeList(); }
|
onchange: function() { refreshConfigNodeList(); }
|
||||||
});
|
});
|
||||||
|
RED.actions.add("core:show-config-tab",function() {RED.sidebar.show('config')});
|
||||||
RED.menu.setAction('menu-item-config-nodes',function() {
|
|
||||||
RED.sidebar.show('config');
|
|
||||||
})
|
|
||||||
|
|
||||||
$("#workspace-config-node-collapse-all").on("click", function(e) {
|
$("#workspace-config-node-collapse-all").on("click", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -42,7 +42,7 @@ RED.sidebar.info = (function() {
|
|||||||
content: content,
|
content: content,
|
||||||
enableOnEdit: true
|
enableOnEdit: true
|
||||||
});
|
});
|
||||||
|
RED.actions.add("core:show-info-tab",show);
|
||||||
}
|
}
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
|
@ -13,6 +13,8 @@ RED.typeSearch = (function() {
|
|||||||
var activeFilter = "";
|
var activeFilter = "";
|
||||||
var addCallback;
|
var addCallback;
|
||||||
|
|
||||||
|
var typesUsed = {};
|
||||||
|
|
||||||
function search(val) {
|
function search(val) {
|
||||||
activeFilter = val.toLowerCase();
|
activeFilter = val.toLowerCase();
|
||||||
var visible = searchResults.editableList('filter');
|
var visible = searchResults.editableList('filter');
|
||||||
@ -44,7 +46,7 @@ RED.typeSearch = (function() {
|
|||||||
//shade = $('<div>',{class:"red-ui-type-search-shade"}).appendTo("#main-container");
|
//shade = $('<div>',{class:"red-ui-type-search-shade"}).appendTo("#main-container");
|
||||||
dialog = $("<div>",{id:"red-ui-type-search",class:"red-ui-search red-ui-type-search"}).appendTo("#main-container");
|
dialog = $("<div>",{id:"red-ui-type-search",class:"red-ui-search red-ui-type-search"}).appendTo("#main-container");
|
||||||
var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog);
|
var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog);
|
||||||
searchInput = $('<input type="text" placeholder="add a node...">').appendTo(searchDiv).searchBox({
|
searchInput = $('<input type="text">').attr("placeholder",RED._("search.addNode")).appendTo(searchDiv).searchBox({
|
||||||
delay: 50,
|
delay: 50,
|
||||||
change: function() {
|
change: function() {
|
||||||
search($(this).val());
|
search($(this).val());
|
||||||
@ -93,12 +95,17 @@ RED.typeSearch = (function() {
|
|||||||
if (activeFilter === "" ) {
|
if (activeFilter === "" ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (data.recent || data.common) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return (activeFilter==="")||(data.index.indexOf(activeFilter) > -1);
|
return (activeFilter==="")||(data.index.indexOf(activeFilter) > -1);
|
||||||
},
|
},
|
||||||
addItem: function(container,i,object) {
|
addItem: function(container,i,object) {
|
||||||
var def = object.def;
|
var def = object.def;
|
||||||
object.index = object.type.toLowerCase();
|
object.index = object.type.toLowerCase();
|
||||||
|
if (object.separator) {
|
||||||
|
container.addClass("red-ui-search-result-separator")
|
||||||
|
}
|
||||||
var div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container);
|
var div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container);
|
||||||
|
|
||||||
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div);
|
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div);
|
||||||
@ -118,19 +125,17 @@ RED.typeSearch = (function() {
|
|||||||
var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
||||||
$('<div/>',{class:"palette_icon",style:"background-image: url(icons/"+icon_url+")"}).appendTo(iconContainer);
|
$('<div/>',{class:"palette_icon",style:"background-image: url(icons/"+icon_url+")"}).appendTo(iconContainer);
|
||||||
|
|
||||||
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
|
if (def.inputs > 0) {
|
||||||
|
$('<div/>',{class:"red-ui-search-result-node-port"}).appendTo(nodeDiv);
|
||||||
var label = object.type;
|
}
|
||||||
if (typeof def.paletteLabel !== "undefined") {
|
if (def.outputs > 0) {
|
||||||
try {
|
$('<div/>',{class:"red-ui-search-result-node-port red-ui-search-result-node-output"}).appendTo(nodeDiv);
|
||||||
label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||"";
|
|
||||||
label += " ("+object.type+")";
|
|
||||||
object.index += "|"+label.toLowerCase();
|
|
||||||
} catch(err) {
|
|
||||||
console.log("Definition error: "+object.type+".paletteLabel",err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
|
||||||
|
|
||||||
|
var label = object.label;
|
||||||
|
object.index += "|"+label.toLowerCase();
|
||||||
|
|
||||||
$('<div>',{class:"red-ui-search-result-node-label"}).html(label).appendTo(contentDiv);
|
$('<div>',{class:"red-ui-search-result-node-label"}).html(label).appendTo(contentDiv);
|
||||||
|
|
||||||
@ -145,6 +150,7 @@ RED.typeSearch = (function() {
|
|||||||
}
|
}
|
||||||
function confirm(def) {
|
function confirm(def) {
|
||||||
hide();
|
hide();
|
||||||
|
typesUsed[def.type] = Date.now();
|
||||||
addCallback(def.type);
|
addCallback(def.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +168,7 @@ RED.typeSearch = (function() {
|
|||||||
}
|
}
|
||||||
function show(opts) {
|
function show(opts) {
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
RED.keyboard.add("*",/* ESCAPE */ 27,function(){hide();d3.event.preventDefault();});
|
RED.keyboard.add("*","escape",function(){hide()});
|
||||||
if (dialog === null) {
|
if (dialog === null) {
|
||||||
createDialog();
|
createDialog();
|
||||||
}
|
}
|
||||||
@ -189,7 +195,7 @@ RED.typeSearch = (function() {
|
|||||||
}
|
}
|
||||||
function hide(fast) {
|
function hide(fast) {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
RED.keyboard.remove(/* ESCAPE */ 27);
|
RED.keyboard.remove("escape");
|
||||||
visible = false;
|
visible = false;
|
||||||
if (dialog !== null) {
|
if (dialog !== null) {
|
||||||
searchResultsDiv.slideUp(fast?50:200,function() {
|
searchResultsDiv.slideUp(fast?50:200,function() {
|
||||||
@ -205,41 +211,84 @@ RED.typeSearch = (function() {
|
|||||||
$(document).off('click.type-search');
|
$(document).off('click.type-search');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTypeLabel(type, def) {
|
||||||
|
var label = type;
|
||||||
|
if (typeof def.paletteLabel !== "undefined") {
|
||||||
|
try {
|
||||||
|
label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||"";
|
||||||
|
label += " ("+type+")";
|
||||||
|
} catch(err) {
|
||||||
|
console.log("Definition error: "+type+".paletteLabel",err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
function refreshTypeList() {
|
function refreshTypeList() {
|
||||||
|
var i;
|
||||||
searchResults.editableList('empty');
|
searchResults.editableList('empty');
|
||||||
searchInput.searchBox('value','');
|
searchInput.searchBox('value','');
|
||||||
selected = -1;
|
selected = -1;
|
||||||
var common = {
|
var common = [
|
||||||
"debug" : false,
|
'debug','inject','function','change','switch'
|
||||||
"inject" : false,
|
];
|
||||||
"function": false
|
|
||||||
};
|
var recentlyUsed = Object.keys(typesUsed);
|
||||||
var nodeTypes = RED.nodes.registry.getNodeTypes().filter(function(n) {
|
recentlyUsed.sort(function(a,b) {
|
||||||
if (common.hasOwnProperty(n)) {
|
return typesUsed[b]-typesUsed[a];
|
||||||
common[n] = true;
|
});
|
||||||
return false;
|
recentlyUsed = recentlyUsed.filter(function(t) {
|
||||||
}
|
return common.indexOf(t) === -1;
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
// Just in case a core node has been disabled
|
|
||||||
if (common["function"]) {
|
|
||||||
nodeTypes.unshift("function");
|
|
||||||
}
|
|
||||||
if (common["inject"]) {
|
|
||||||
nodeTypes.unshift("inject");
|
|
||||||
}
|
|
||||||
if (common["debug"]) {
|
|
||||||
nodeTypes.unshift("debug");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var items = [];
|
||||||
var i;
|
RED.nodes.registry.getNodeTypes().forEach(function(t) {
|
||||||
for (i=0;i<nodeTypes.length;i++) {
|
|
||||||
var t = nodeTypes[i];
|
|
||||||
var def = RED.nodes.getType(t);
|
var def = RED.nodes.getType(t);
|
||||||
if (def.category !== 'config' && t !== 'unknown') {
|
if (def.category !== 'config' && t !== 'unknown') {
|
||||||
searchResults.editableList('addItem',{type:t,def: def})
|
items.push({type:t,def: def, label:getTypeLabel(t,def)});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
items.sort(function(a,b) {
|
||||||
|
var al = a.label.toLowerCase();
|
||||||
|
var bl = b.label.toLowerCase();
|
||||||
|
if (al < bl) {
|
||||||
|
return -1;
|
||||||
|
} else if (al === bl) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var commonCount = 0;
|
||||||
|
var item;
|
||||||
|
for(i=0;i<common.length;i++) {
|
||||||
|
item = {
|
||||||
|
type: common[i],
|
||||||
|
common: true,
|
||||||
|
def: RED.nodes.getType(common[i])
|
||||||
|
};
|
||||||
|
item.label = getTypeLabel(item.type,item.def);
|
||||||
|
if (i === common.length-1) {
|
||||||
|
item.separator = true;
|
||||||
|
}
|
||||||
|
searchResults.editableList('addItem', item);
|
||||||
|
}
|
||||||
|
for(i=0;i<Math.min(5,recentlyUsed.length);i++) {
|
||||||
|
item = {
|
||||||
|
type:recentlyUsed[i],
|
||||||
|
def: RED.nodes.getType(recentlyUsed[i]),
|
||||||
|
recent: true
|
||||||
|
};
|
||||||
|
item.label = getTypeLabel(item.type,item.def);
|
||||||
|
if (i === recentlyUsed.length-1) {
|
||||||
|
item.separator = true;
|
||||||
|
}
|
||||||
|
searchResults.editableList('addItem', item);
|
||||||
|
}
|
||||||
|
for (i=0;i<items.length;i++) {
|
||||||
|
searchResults.editableList('addItem', items[i]);
|
||||||
}
|
}
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
selected = 0;
|
selected = 0;
|
||||||
@ -247,23 +296,7 @@ RED.typeSearch = (function() {
|
|||||||
},100);
|
},100);
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
|
||||||
// RED.keyboard.add("*",/* . */ 190,{ctrl:true},function(){if (!disabled) { show(); } d3.event.preventDefault();});
|
|
||||||
// RED.events.on("editor:open",function() { disabled = true; });
|
|
||||||
// RED.events.on("editor:close",function() { disabled = false; });
|
|
||||||
// RED.events.on("palette-editor:open",function() { disabled = true; });
|
|
||||||
// RED.events.on("palette-editor:close",function() { disabled = false; });
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// $("#header-shade").on('mousedown',hide);
|
|
||||||
// $("#editor-shade").on('mousedown',hide);
|
|
||||||
// $("#palette-shade").on('mousedown',hide);
|
|
||||||
// $("#sidebar-shade").on('mousedown',hide);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init,
|
|
||||||
show: show,
|
show: show,
|
||||||
hide: hide
|
hide: hide
|
||||||
};
|
};
|
||||||
|
@ -19,6 +19,9 @@ RED.utils = (function() {
|
|||||||
function formatString(str) {
|
function formatString(str) {
|
||||||
return str.replace(/\r?\n/g,"↵").replace(/\t/g,"→");
|
return str.replace(/\r?\n/g,"↵").replace(/\t/g,"→");
|
||||||
}
|
}
|
||||||
|
function sanitize(m) {
|
||||||
|
return m.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||||
|
}
|
||||||
|
|
||||||
function buildMessageSummaryValue(value) {
|
function buildMessageSummaryValue(value) {
|
||||||
var result;
|
var result;
|
||||||
@ -35,9 +38,11 @@ RED.utils = (function() {
|
|||||||
result = $('<span class="debug-message-object-value debug-message-type-meta">object</span>');
|
result = $('<span class="debug-message-object-value debug-message-type-meta">object</span>');
|
||||||
}
|
}
|
||||||
} else if (typeof value === 'string') {
|
} else if (typeof value === 'string') {
|
||||||
subvalue = value;
|
var subvalue;
|
||||||
if (subvalue.length > 30) {
|
if (value.length > 30) {
|
||||||
subvalue = subvalue.substring(0,30)+"…";
|
subvalue = sanitize(value.substring(0,30))+"…";
|
||||||
|
} else {
|
||||||
|
subvalue = sanitize(value);
|
||||||
}
|
}
|
||||||
result = $('<span class="debug-message-object-value debug-message-type-string"></span>').html('"'+formatString(subvalue)+'"');
|
result = $('<span class="debug-message-object-value debug-message-type-string"></span>').html('"'+formatString(subvalue)+'"');
|
||||||
} else {
|
} else {
|
||||||
@ -68,7 +73,7 @@ RED.utils = (function() {
|
|||||||
var entryObj;
|
var entryObj;
|
||||||
var header;
|
var header;
|
||||||
var headerHead;
|
var headerHead;
|
||||||
var value,subvalue;
|
var value;
|
||||||
var element = $('<span class="debug-message-element"></span>');
|
var element = $('<span class="debug-message-element"></span>');
|
||||||
if (!key) {
|
if (!key) {
|
||||||
element.addClass("debug-message-top-level");
|
element.addClass("debug-message-top-level");
|
||||||
@ -84,7 +89,7 @@ RED.utils = (function() {
|
|||||||
|
|
||||||
var isArray = Array.isArray(obj);
|
var isArray = Array.isArray(obj);
|
||||||
var isArrayObject = false;
|
var isArrayObject = false;
|
||||||
if (obj && typeof obj === 'object' && obj.hasOwnProperty('type') && obj.hasOwnProperty('data')) {
|
if (obj && typeof obj === 'object' && obj.hasOwnProperty('type') && obj.hasOwnProperty('data') && ((obj.__encoded__ && obj.type === 'array') || obj.type === 'Buffer')) {
|
||||||
isArray = true;
|
isArray = true;
|
||||||
isArrayObject = true;
|
isArrayObject = true;
|
||||||
}
|
}
|
||||||
@ -98,23 +103,30 @@ RED.utils = (function() {
|
|||||||
makeExpandable(header, function() {
|
makeExpandable(header, function() {
|
||||||
$('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html(typeHint||'string').appendTo(header);
|
$('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html(typeHint||'string').appendTo(header);
|
||||||
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element);
|
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element);
|
||||||
$('<pre class="debug-message-type-string"></pre>').html(obj).appendTo(row);
|
$('<pre class="debug-message-type-string"></pre>').text(obj).appendTo(row);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$('<span class="debug-message-type-string debug-message-object-header"></span>').html('"'+formatString(obj)+'"').appendTo(entryObj);
|
$('<span class="debug-message-type-string debug-message-object-header"></span>').html('"'+formatString(sanitize(obj))+'"').appendTo(entryObj);
|
||||||
|
|
||||||
|
|
||||||
} else if (typeof obj === 'number') {
|
} else if (typeof obj === 'number') {
|
||||||
e = $('<span class="debug-message-type-number"></span>').text(""+obj).appendTo(entryObj);
|
e = $('<span class="debug-message-type-number"></span>').text(""+obj).appendTo(entryObj);
|
||||||
e.click(function(evt) {
|
if (Number.isInteger(obj) && (obj >= 0)) { // if it's a +ve integer
|
||||||
var format = $(this).data('format');
|
e.addClass("debug-message-type-number-toggle");
|
||||||
if (format === 'hex') {
|
e.click(function(evt) {
|
||||||
$(this).text(""+obj).data('format','dec');
|
var format = $(this).data('format') || "date";
|
||||||
} else {
|
if (format === 'dec') {
|
||||||
$(this).text("0x"+(obj).toString(16)).data('format','hex');
|
$(this).text(""+obj).data('format','date');
|
||||||
}
|
} else if ((format === 'date') && (obj.toString().length===13) && (obj<=2147483647000)) {
|
||||||
evt.preventDefault();
|
$(this).text((new Date(obj)).toISOString()).data('format','hex');
|
||||||
});
|
} else if ((format === 'date') && (obj.toString().length===10) && (obj<=2147483647)) {
|
||||||
|
$(this).text((new Date(obj*1000)).toISOString()).data('format','hex');
|
||||||
|
} else {
|
||||||
|
$(this).text("0x"+(obj).toString(16)).data('format','dec');
|
||||||
|
}
|
||||||
|
evt.preventDefault();
|
||||||
|
});
|
||||||
|
}
|
||||||
} else if (isArray) {
|
} else if (isArray) {
|
||||||
element.addClass('collapsed');
|
element.addClass('collapsed');
|
||||||
|
|
||||||
@ -155,7 +167,7 @@ RED.utils = (function() {
|
|||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
$('<pre class="debug-message-type-string"></pre>').html(stringEncoding).appendTo(sr);
|
$('<pre class="debug-message-type-string"></pre>').text(stringEncoding).appendTo(sr);
|
||||||
var bufferOpts = $('<span class="debug-message-buffer-opts"></span>').appendTo(headerHead);
|
var bufferOpts = $('<span class="debug-message-buffer-opts"></span>').appendTo(headerHead);
|
||||||
$('<a href="#"></a>').addClass('selected').html('raw').appendTo(bufferOpts).click(function(e) {
|
$('<a href="#"></a>').addClass('selected').html('raw').appendTo(bufferOpts).click(function(e) {
|
||||||
if ($(this).text() === 'raw') {
|
if ($(this).text() === 'raw') {
|
||||||
|
@ -267,6 +267,7 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
RED.events.on("workspace:change",function(event) {
|
RED.events.on("workspace:change",function(event) {
|
||||||
var chart = $("#chart");
|
var chart = $("#chart");
|
||||||
if (event.old !== 0) {
|
if (event.old !== 0) {
|
||||||
@ -384,28 +385,47 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
RED.keyboard.add("workspace",/* backspace */ 8,function(){deleteSelection();d3.event.preventDefault();});
|
RED.actions.add("core:copy",copySelection);
|
||||||
RED.keyboard.add("workspace",/* delete */ 46,function(){deleteSelection();d3.event.preventDefault();});
|
RED.actions.add("core:cut",function(){copySelection();deleteSelection();});
|
||||||
RED.keyboard.add("workspace",/* enter */ 13, function() { editSelection(); d3.event.preventDefault();});
|
RED.actions.add("core:paste",function(){importNodes(clipboard);});
|
||||||
|
RED.actions.add("core:delete",deleteSelection);
|
||||||
|
RED.actions.add("core:edit",editSelection);
|
||||||
|
RED.actions.add("core:undo",RED.history.pop);
|
||||||
|
RED.actions.add("core:select-all",selectAll);
|
||||||
|
RED.actions.add("core:zoom-in",zoomIn);
|
||||||
|
RED.actions.add("core:zoom-out",zoomOut);
|
||||||
|
RED.actions.add("core:zoom-reset",zoomZero);
|
||||||
|
|
||||||
RED.keyboard.add("workspace",/* c */ 67,{ctrl:true},function(){copySelection();d3.event.preventDefault();});
|
RED.actions.add("core:toggle-show-grid",function(state) {
|
||||||
RED.keyboard.add("workspace",/* x */ 88,{ctrl:true},function(){copySelection();deleteSelection();d3.event.preventDefault();});
|
if (state === undefined) {
|
||||||
|
RED.menu.toggleSelected("menu-item-view-show-grid");
|
||||||
|
} else {
|
||||||
|
toggleShowGrid(state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RED.actions.add("core:toggle-snap-grid",function(state) {
|
||||||
|
if (state === undefined) {
|
||||||
|
RED.menu.toggleSelected("menu-item-view-snap-grid");
|
||||||
|
} else {
|
||||||
|
toggleSnapGrid(state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RED.actions.add("core:toggle-status",function(state) {
|
||||||
|
if (state === undefined) {
|
||||||
|
RED.menu.toggleSelected("menu-item-status");
|
||||||
|
} else {
|
||||||
|
toggleStatus(state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
RED.keyboard.add("workspace",/* z */ 90,{ctrl:true},function(){RED.history.pop();});
|
RED.actions.add("core:move-selection-up", function() { moveSelection(0,-1);});
|
||||||
RED.keyboard.add("workspace",/* a */ 65,{ctrl:true},function(){selectAll();d3.event.preventDefault();});
|
RED.actions.add("core:step-selection-up", function() { moveSelection(0,-20);});
|
||||||
RED.keyboard.add("*",/* = */ 187,{ctrl:true},function(){zoomIn();d3.event.preventDefault();});
|
RED.actions.add("core:move-selection-right", function() { moveSelection(1,0);});
|
||||||
RED.keyboard.add("*",/* - */ 189,{ctrl:true},function(){zoomOut();d3.event.preventDefault();});
|
RED.actions.add("core:step-selection-right", function() { moveSelection(20,0);});
|
||||||
RED.keyboard.add("*",/* 0 */ 48,{ctrl:true},function(){zoomZero();d3.event.preventDefault();});
|
RED.actions.add("core:move-selection-down", function() { moveSelection(0,1);});
|
||||||
RED.keyboard.add("workspace",/* v */ 86,{ctrl:true},function(){importNodes(clipboard);d3.event.preventDefault();});
|
RED.actions.add("core:step-selection-down", function() { moveSelection(0,20);});
|
||||||
|
RED.actions.add("core:move-selection-left", function() { moveSelection(-1,0);});
|
||||||
RED.keyboard.add("workspace",/* up */ 38, function() { moveSelection(0,-1);d3.event.preventDefault();},endKeyboardMove);
|
RED.actions.add("core:step-selection-left", function() { moveSelection(-20,0);});
|
||||||
RED.keyboard.add("workspace",/* up */ 38, {shift:true}, function() { moveSelection(0,-20); d3.event.preventDefault();},endKeyboardMove);
|
|
||||||
RED.keyboard.add("workspace",/* down */ 40, function() { moveSelection(0,1);d3.event.preventDefault();},endKeyboardMove);
|
|
||||||
RED.keyboard.add("workspace",/* down */ 40, {shift:true}, function() { moveSelection(0,20); d3.event.preventDefault();},endKeyboardMove);
|
|
||||||
RED.keyboard.add("workspace",/* left */ 37, function() { moveSelection(-1,0);d3.event.preventDefault();},endKeyboardMove);
|
|
||||||
RED.keyboard.add("workspace",/* left */ 37, {shift:true}, function() { moveSelection(-20,0); d3.event.preventDefault();},endKeyboardMove);
|
|
||||||
RED.keyboard.add("workspace",/* right */ 39, function() { moveSelection(1,0);d3.event.preventDefault();},endKeyboardMove);
|
|
||||||
RED.keyboard.add("workspace",/* right */ 39, {shift:true}, function() { moveSelection(20,0); d3.event.preventDefault();},endKeyboardMove);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -959,7 +979,7 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mouse_mode == RED.state.IMPORT_DRAGGING) {
|
if (mouse_mode == RED.state.IMPORT_DRAGGING) {
|
||||||
RED.keyboard.remove(/* ESCAPE */ 27);
|
RED.keyboard.remove("escape");
|
||||||
updateActiveNodes();
|
updateActiveNodes();
|
||||||
RED.nodes.dirty(true);
|
RED.nodes.dirty(true);
|
||||||
}
|
}
|
||||||
@ -1103,6 +1123,7 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function endKeyboardMove() {
|
function endKeyboardMove() {
|
||||||
|
endMoveSet = false;
|
||||||
if (moving_set.length > 0) {
|
if (moving_set.length > 0) {
|
||||||
var ns = [];
|
var ns = [];
|
||||||
for (var i=0;i<moving_set.length;i++) {
|
for (var i=0;i<moving_set.length;i++) {
|
||||||
@ -1117,14 +1138,21 @@ RED.view = (function() {
|
|||||||
RED.nodes.dirty(true);
|
RED.nodes.dirty(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var endMoveSet = false;
|
||||||
function moveSelection(dx,dy) {
|
function moveSelection(dx,dy) {
|
||||||
if (moving_set.length > 0) {
|
if (moving_set.length > 0) {
|
||||||
|
if (!endMoveSet) {
|
||||||
|
$(document).one('keyup',endKeyboardMove);
|
||||||
|
endMoveSet = true;
|
||||||
|
}
|
||||||
var minX = 0;
|
var minX = 0;
|
||||||
var minY = 0;
|
var minY = 0;
|
||||||
var node;
|
var node;
|
||||||
|
|
||||||
for (var i=0;i<moving_set.length;i++) {
|
for (var i=0;i<moving_set.length;i++) {
|
||||||
node = moving_set[i];
|
node = moving_set[i];
|
||||||
|
node.n.changed = true;
|
||||||
|
node.n.dirty = true;
|
||||||
if (node.ox == null && node.oy == null) {
|
if (node.ox == null && node.oy == null) {
|
||||||
node.ox = node.n.x;
|
node.ox = node.n.x;
|
||||||
node.oy = node.n.y;
|
node.oy = node.n.y;
|
||||||
@ -1440,7 +1468,7 @@ RED.view = (function() {
|
|||||||
//var pos = [touch0.pageX,touch0.pageY];
|
//var pos = [touch0.pageX,touch0.pageY];
|
||||||
//RED.touch.radialMenu.show(d3.select(this),pos);
|
//RED.touch.radialMenu.show(d3.select(this),pos);
|
||||||
if (mouse_mode == RED.state.IMPORT_DRAGGING) {
|
if (mouse_mode == RED.state.IMPORT_DRAGGING) {
|
||||||
RED.keyboard.remove(/* ESCAPE */ 27);
|
RED.keyboard.remove("escape");
|
||||||
|
|
||||||
if (activeSpliceLink) {
|
if (activeSpliceLink) {
|
||||||
// TODO: DRY - droppable/nodeMouseDown/canvasMouseUp
|
// TODO: DRY - droppable/nodeMouseDown/canvasMouseUp
|
||||||
@ -2437,8 +2465,8 @@ RED.view = (function() {
|
|||||||
node.n._def.outputs > 0;
|
node.n._def.outputs > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RED.keyboard.add("*",/* ESCAPE */ 27,function(){
|
RED.keyboard.add("*","escape",function(){
|
||||||
RED.keyboard.remove(/* ESCAPE */ 27);
|
RED.keyboard.remove("escape");
|
||||||
clearSelection();
|
clearSelection();
|
||||||
RED.history.pop();
|
RED.history.pop();
|
||||||
mouse_mode = 0;
|
mouse_mode = 0;
|
||||||
@ -2483,6 +2511,24 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleShowGrid(state) {
|
||||||
|
if (state) {
|
||||||
|
grid.style("visibility","visible");
|
||||||
|
} else {
|
||||||
|
grid.style("visibility","hidden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function toggleSnapGrid(state) {
|
||||||
|
snapGrid = state;
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
function toggleStatus(s) {
|
||||||
|
showStatus = s;
|
||||||
|
RED.nodes.eachNode(function(n) { n.dirty = true;});
|
||||||
|
//TODO: subscribe/unsubscribe here
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
state:function(state) {
|
state:function(state) {
|
||||||
@ -2502,16 +2548,6 @@ RED.view = (function() {
|
|||||||
},
|
},
|
||||||
focus: focusView,
|
focus: focusView,
|
||||||
importNodes: importNodes,
|
importNodes: importNodes,
|
||||||
status: function(s) {
|
|
||||||
if (s == null) {
|
|
||||||
return showStatus;
|
|
||||||
} else {
|
|
||||||
showStatus = s;
|
|
||||||
RED.nodes.eachNode(function(n) { n.dirty = true;});
|
|
||||||
//TODO: subscribe/unsubscribe here
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
calculateTextWidth: calculateTextWidth,
|
calculateTextWidth: calculateTextWidth,
|
||||||
select: function(selection) {
|
select: function(selection) {
|
||||||
if (typeof selection !== "undefined") {
|
if (typeof selection !== "undefined") {
|
||||||
@ -2538,17 +2574,6 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
return selection;
|
return selection;
|
||||||
},
|
},
|
||||||
toggleShowGrid: function(state) {
|
|
||||||
if (state) {
|
|
||||||
grid.style("visibility","visible");
|
|
||||||
} else {
|
|
||||||
grid.style("visibility","hidden");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toggleSnapGrid: function(state) {
|
|
||||||
snapGrid = state;
|
|
||||||
redraw();
|
|
||||||
},
|
|
||||||
scale: function() {
|
scale: function() {
|
||||||
return scaleFactor;
|
return scaleFactor;
|
||||||
},
|
},
|
||||||
|
@ -170,6 +170,9 @@ RED.workspaces = (function() {
|
|||||||
createWorkspaceTabs();
|
createWorkspaceTabs();
|
||||||
RED.events.on("sidebar:resize",workspace_tabs.resize);
|
RED.events.on("sidebar:resize",workspace_tabs.resize);
|
||||||
|
|
||||||
|
RED.actions.add("core:show-next-tab",workspace_tabs.nextTab);
|
||||||
|
RED.actions.add("core:show-previous-tab",workspace_tabs.previousTab);
|
||||||
|
|
||||||
RED.menu.setAction('menu-item-workspace-delete',function() {
|
RED.menu.setAction('menu-item-workspace-delete',function() {
|
||||||
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
|
deleteWorkspace(RED.nodes.workspace(activeWorkspace));
|
||||||
});
|
});
|
||||||
@ -177,6 +180,14 @@ RED.workspaces = (function() {
|
|||||||
$(window).resize(function() {
|
$(window).resize(function() {
|
||||||
workspace_tabs.resize();
|
workspace_tabs.resize();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RED.actions.add("core:add-flow",addWorkspace);
|
||||||
|
RED.actions.add("core:edit-flow",editWorkspace);
|
||||||
|
RED.actions.add("core:remove-flow",removeWorkspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
function editWorkspace(id) {
|
||||||
|
showRenameWorkspaceDialog(id||activeWorkspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeWorkspace(ws) {
|
function removeWorkspace(ws) {
|
||||||
@ -201,9 +212,7 @@ RED.workspaces = (function() {
|
|||||||
add: addWorkspace,
|
add: addWorkspace,
|
||||||
remove: removeWorkspace,
|
remove: removeWorkspace,
|
||||||
order: setWorkspaceOrder,
|
order: setWorkspaceOrder,
|
||||||
edit: function(id) {
|
edit: editWorkspace,
|
||||||
showRenameWorkspaceDialog(id||activeWorkspace);
|
|
||||||
},
|
|
||||||
contains: function(id) {
|
contains: function(id) {
|
||||||
return workspace_tabs.contains(id);
|
return workspace_tabs.contains(id);
|
||||||
},
|
},
|
||||||
|
8
editor/sass/ace.scss
Normal file
8
editor/sass/ace.scss
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.ace_gutter {
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
}
|
||||||
|
.ace_scroller {
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
@ -51,24 +51,21 @@
|
|||||||
border-right: 8px solid #eee;
|
border-right: 8px solid #eee;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
.debug-message-date {
|
.debug-message-meta {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
font-size: 9px;
|
font-size: 10px;
|
||||||
color: #aaa;
|
color: #777;
|
||||||
|
}
|
||||||
|
.debug-message-date {
|
||||||
padding: 1px 5px 1px 1px;
|
padding: 1px 5px 1px 1px;
|
||||||
}
|
}
|
||||||
.debug-message-topic {
|
.debug-message-topic {
|
||||||
display: block;
|
display: block;
|
||||||
background: #fff;
|
|
||||||
padding: 1px;
|
|
||||||
font-size: 10px;
|
|
||||||
color: #a66;
|
color: #a66;
|
||||||
}
|
}
|
||||||
.debug-message-name {
|
.debug-message-name {
|
||||||
background: #fff;
|
|
||||||
padding: 1px 5px;
|
padding: 1px 5px;
|
||||||
font-size: 9px;
|
color: #777;
|
||||||
color: #aac;
|
|
||||||
}
|
}
|
||||||
.debug-message-payload {
|
.debug-message-payload {
|
||||||
display: block;
|
display: block;
|
||||||
@ -153,7 +150,8 @@
|
|||||||
.debug-message-type-string { color: #b72828; }
|
.debug-message-type-string { color: #b72828; }
|
||||||
.debug-message-type-null { color: #666; font-style: italic;}
|
.debug-message-type-null { color: #666; font-style: italic;}
|
||||||
.debug-message-type-meta { color: #666; font-style: italic;}
|
.debug-message-type-meta { color: #666; font-style: italic;}
|
||||||
.debug-message-type-number { color: #2033d6;cursor: pointer;}
|
.debug-message-type-number { color: #2033d6; };
|
||||||
|
.debug-message-type-number-toggle { cursor: pointer;}
|
||||||
|
|
||||||
.debug-message-expandable {
|
.debug-message-expandable {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -21,30 +21,67 @@
|
|||||||
.red-ui-editableList-container {
|
.red-ui-editableList-container {
|
||||||
border-radius:1px;
|
border-radius:1px;
|
||||||
padding:0;
|
padding:0;
|
||||||
|
background: #f9f9f9;
|
||||||
}
|
}
|
||||||
ol {
|
#node-dialog-view-diff-diff {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top:10px;
|
top:80px;
|
||||||
bottom:10px;
|
bottom:10px;
|
||||||
left:10px;
|
left:10px;
|
||||||
right:10px;
|
right:10px;
|
||||||
li {
|
li {
|
||||||
|
background: #f9f9f9;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
border: none;
|
border: none;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.red-ui-editableList-item-content {
|
.red-ui-editableList-item-content {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
// padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#node-dialog-view-diff-headers {
|
||||||
|
position: absolute;
|
||||||
|
left:17px;
|
||||||
|
right:32px;
|
||||||
|
top: 55px;
|
||||||
|
height: 25px;
|
||||||
|
.node-diff-node-entry-cell:not(:first-child) {
|
||||||
|
background: #f9f9f9;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid $secondary-border-color;
|
||||||
|
border-color:$secondary-border-color;
|
||||||
|
}
|
||||||
|
.node-diff-node-entry-cell:last-child {
|
||||||
|
border-right: 1px solid $secondary-border-color;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-diff-toolbar {
|
||||||
|
position:absolute;
|
||||||
|
top:0;
|
||||||
|
left:0;
|
||||||
|
right:0;
|
||||||
|
height: 43px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #666;
|
||||||
|
text-align: right;
|
||||||
|
padding: 8px 10px;
|
||||||
|
background: #f3f3f3;
|
||||||
|
border-bottom: 1px solid $secondary-border-color;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.node-diff-tab {
|
.node-diff-tab {
|
||||||
border: 1px solid $secondary-border-color;
|
background: #fff;
|
||||||
border-radius: 3px;
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
&.collapsed {
|
&.collapsed {
|
||||||
.node-diff-tab-title > .node-diff-chevron {
|
.node-diff-tab-title .node-diff-chevron {
|
||||||
transform: rotate(-90deg);
|
transform: rotate(-90deg);
|
||||||
}
|
}
|
||||||
.node-diff-node-entry {
|
.node-diff-node-entry {
|
||||||
@ -53,21 +90,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.node-diff-tab-stats {
|
.node-diff-tab-stats {
|
||||||
position: absolute;
|
font-size: 0.9em;
|
||||||
left: 50%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.node-diff-chevron {
|
.node-diff-chevron {
|
||||||
|
display: inline-block;
|
||||||
width: 15px;
|
width: 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 3px 5px 3px 5px;
|
margin-left: 3px;
|
||||||
transition: transform 0.1s ease-in-out;
|
transition: transform 0.1s ease-in-out;
|
||||||
|
|
||||||
}
|
}
|
||||||
.node-diff-node-entry {
|
.node-diff-node-entry {
|
||||||
padding: 0 0 0 5px;
|
margin-left: 20px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
}
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
border-bottom: 1px solid $secondary-border-color;
|
border-bottom: 1px solid #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.collapsed {
|
&.collapsed {
|
||||||
@ -78,25 +120,80 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&:not(.collapsed) {
|
||||||
|
.node-diff-node-entry-cell:not(:first-child) {
|
||||||
|
//display: none;
|
||||||
|
}
|
||||||
|
.node-diff-node-entry-cell:first-child {
|
||||||
|
//width: 100%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
width: 100%;
|
table-layout:fixed;
|
||||||
table-layout:fixed;
|
|
||||||
|
// Fix for table-layout: fixed on safari:
|
||||||
|
max-width: none;
|
||||||
|
width: auto;
|
||||||
|
min-width: 100%;
|
||||||
}
|
}
|
||||||
td, th {
|
td, th {
|
||||||
border: 1px solid $secondary-border-color;
|
border: 1px solid $secondary-border-color;
|
||||||
padding: 3px 5px;
|
padding: 0 0 0 3px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
tr {
|
||||||
td:nth-child(1) {
|
vertical-align: top;
|
||||||
width: 150px;
|
&:first-child td {
|
||||||
|
white-space:nowrap;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td:first-child {
|
||||||
|
width: 140px;
|
||||||
}
|
}
|
||||||
td:not(:first-child) {
|
td:not(:first-child) {
|
||||||
width: calc(50% - 150px);
|
width: calc( 100% - 140px);
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
.node-diff-status {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tr:not(.node-diff-property-header) {
|
||||||
|
.node-diff-status {
|
||||||
|
width: 12px;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.node-diff-three-way {
|
||||||
|
.node-diff-node-entry-cell {
|
||||||
|
width: calc((100% - 220px) / 2);
|
||||||
|
&:first-child {
|
||||||
|
width: 220px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td:not(:first-child) {
|
||||||
|
width: calc( (100% - 140px) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-diff-node-entry {
|
||||||
|
.node-diff-node-entry-cell {
|
||||||
|
width: calc((100% + 20px - 220px) / 2);
|
||||||
|
&:first-child {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.node-diff-column {
|
.node-diff-column {
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
height:100%;
|
height:100%;
|
||||||
@ -108,18 +205,26 @@
|
|||||||
border-right: 1px solid $secondary-border-color
|
border-right: 1px solid $secondary-border-color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.node-diff-tab-title {
|
.node-diff-tab-title {
|
||||||
padding: 3px 3px 3px 0;
|
cursor: pointer;
|
||||||
background: #f6f6f6;
|
padding: 0;
|
||||||
|
// background: #f6f6f6;
|
||||||
|
}
|
||||||
|
.node-diff-tab-title-meta {
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
.node-diff-node-entry-header {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.node-diff-node-entry-node {
|
.node-diff-node-entry-node {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
width: 24px;
|
width: 18px;
|
||||||
height: 20px;
|
height: 15px;
|
||||||
background: #ddd;
|
background: #ddd;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
border: 1px solid #999;
|
border: 1px solid #999;
|
||||||
@ -128,25 +233,89 @@
|
|||||||
background-size: contain;
|
background-size: contain;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.palette-icon {
|
.palette_icon {
|
||||||
width: 16px;
|
background-position: 49% 50%;
|
||||||
|
width: 15px;
|
||||||
}
|
}
|
||||||
.palette_icon_container {
|
.palette_icon_container {
|
||||||
width: 24px;
|
width: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.node-diff-tab-empty {
|
||||||
|
.node-diff-chevron i {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.node-diff-tab-title {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.node-diff-node-deleted {
|
||||||
|
//background: #fadddd;
|
||||||
|
cursor: default !important;
|
||||||
|
.node-diff-status {
|
||||||
|
color: #f80000;
|
||||||
|
}
|
||||||
|
.node-diff-node-entry-node {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.node-diff-node-description {
|
||||||
|
opacity: 0.5;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.node-diff-node-added {
|
||||||
|
//background: #eefaee;
|
||||||
|
cursor: default !important;
|
||||||
|
.node-diff-status {
|
||||||
|
color: #009900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.node-diff-node-moved {
|
||||||
|
//background: #eefaee;
|
||||||
|
.node-diff-status {
|
||||||
|
color: #3f81b3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-diff-node-changed {
|
||||||
|
//background: #fff2ca;
|
||||||
|
.node-diff-status {
|
||||||
|
color: #f89406;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.node-diff-node-unchanged {
|
||||||
|
//background: #fff2ca;
|
||||||
|
.node-diff-status {
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.node-diff-node-conflict {
|
||||||
|
.node-diff-status {
|
||||||
|
color: #9b45ce;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.node-diff-node-entry-title {
|
.node-diff-node-entry-title {
|
||||||
cursor: pointer;
|
display: inline-block;
|
||||||
|
.node-diff-status {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.node-diff-node-entry-properties {
|
.node-diff-node-entry-properties {
|
||||||
margin-left: 30px;
|
margin: 5px ;
|
||||||
margin-right: 8px;
|
|
||||||
margin-bottom:8px;
|
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
.node-diff-status {
|
||||||
|
display: inline-block;
|
||||||
|
height: 20px;
|
||||||
|
margin-left: 5px;
|
||||||
|
vertical-align: top;
|
||||||
|
margin-top: 6px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.node-diff-node-description {
|
.node-diff-node-description {
|
||||||
color: $form-text-color;
|
color: $form-text-color;
|
||||||
margin-left: 5px;
|
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -156,10 +325,192 @@
|
|||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.node-diff-node-meta {
|
||||||
|
float: right;
|
||||||
|
//font-size: 0.9em;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 7px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.node-diff-count { color: #999}
|
.node-diff-count { color: #999}
|
||||||
.node-diff-added { color: #009900}
|
.node-diff-added { color: #009900}
|
||||||
.node-diff-deleted { color: #f80000}
|
.node-diff-deleted { color: #f80000}
|
||||||
.node-diff-changed { color: #f89406}
|
.node-diff-changed { color: #f89406}
|
||||||
.node-diff-conflicted { color: purple}
|
.node-diff-conflicted { color: purple}
|
||||||
|
|
||||||
|
|
||||||
|
.node-diff-node-entry-cell {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: calc( (100% - 20px) / 2);
|
||||||
|
height: 32px;
|
||||||
|
border-left: 1px solid #eee;
|
||||||
|
padding-top: 2px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.node-diff-empty {
|
||||||
|
background: #f3f3f3;
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
20deg,
|
||||||
|
#fff, #fff 5px,
|
||||||
|
#f6f6f6 5px,
|
||||||
|
#f6f6f6 10px
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.node-diff-node-entry-cell:first-child {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
.node-diff-property-cell-label {
|
||||||
|
margin-left: 20px;
|
||||||
|
vertical-align: top;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-left: 8px;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
.node-diff-property-wires {
|
||||||
|
display: inline-block;
|
||||||
|
.node-diff-node-entry-node {
|
||||||
|
width: 18px;
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
|
.palette_icon_container {
|
||||||
|
width: 18px;
|
||||||
|
}
|
||||||
|
.palette_icon {
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
ul,li,ol {
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
list-style-type: none !important;
|
||||||
|
}
|
||||||
|
ol {
|
||||||
|
font-size: 0.9em;
|
||||||
|
margin: 0;
|
||||||
|
& > span {
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
width: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
& > li:not(:last-child) {
|
||||||
|
border-bottom: 1px solid #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.node-diff-node-props .node-diff-node-entry-cell:first-child {
|
||||||
|
padding: 6px 0px;
|
||||||
|
span:not(.node-diff-chevron) {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.node-diff-property-cell {
|
||||||
|
// vertical-align: top;
|
||||||
|
// display:inline-block;
|
||||||
|
//
|
||||||
|
// box-sizing: border-box;
|
||||||
|
// padding: 1px 5px;
|
||||||
|
//min-height: 30px;
|
||||||
|
|
||||||
|
&.node-diff-node-changed {
|
||||||
|
background: #fff2e1 !important;
|
||||||
|
}
|
||||||
|
&.node-diff-node-conflict {
|
||||||
|
background: #ffdad4 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-diff-selectbox {
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
right:0;
|
||||||
|
bottom:0;
|
||||||
|
width: 35px;
|
||||||
|
text-align: center;
|
||||||
|
border-left: 1px solid #eee;
|
||||||
|
margin:0;
|
||||||
|
input {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f3f3f3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-diff-node-entry-conflict.node-diff-select-remote {
|
||||||
|
.node-diff-node-remote {
|
||||||
|
background: #e7ffe3;
|
||||||
|
label {
|
||||||
|
border-left-color: #b8daad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.node-diff-node-local {
|
||||||
|
background: #ffe1e1;
|
||||||
|
label {
|
||||||
|
border-left-color: #e4bcbc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.node-diff-node-entry-conflict.node-diff-select-local {
|
||||||
|
.node-diff-node-local {
|
||||||
|
background: #e7ffe3;
|
||||||
|
label {
|
||||||
|
border-left-color: #b8daad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.node-diff-node-remote {
|
||||||
|
background: #ffe1e1;
|
||||||
|
label {
|
||||||
|
border-left-color: #e4bcbc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#node-dialog-confirm-deploy {
|
||||||
|
.node-dialog-confirm-row {
|
||||||
|
text-align: left; padding-top: 10px;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
font-size: 0.9em;
|
||||||
|
width: 400px;
|
||||||
|
margin: 10px auto;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.node-dialog-confirm-conflict-row {
|
||||||
|
img {
|
||||||
|
vertical-align:middle;
|
||||||
|
height: 30px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
vertical-align:middle;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 30px;
|
||||||
|
width: 30px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
vertical-align: middle;
|
||||||
|
width: calc(100% - 60px);
|
||||||
|
display:inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#node-diff-toolbar-resolved-conflicts .node-diff-status {
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
@ -60,12 +60,31 @@
|
|||||||
.red-ui-search-result {
|
.red-ui-search-result {
|
||||||
padding: 2px 2px 2px 5px;
|
padding: 2px 2px 2px 5px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
border-left-width: 2px;
|
border-left-width: 3px;
|
||||||
border-right-width: 2px;
|
border-right-width: 3px;
|
||||||
|
}
|
||||||
|
.red-ui-search-result-separator {
|
||||||
|
border-bottom: 3px solid #ddd;
|
||||||
}
|
}
|
||||||
.red-ui-search-result-node {
|
.red-ui-search-result-node {
|
||||||
|
position: relative;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 15px;
|
height: 15px;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
.red-ui-search-result-node-port {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
width: 6px;
|
||||||
|
height: 7px;
|
||||||
|
top:4px;
|
||||||
|
left:-4px;
|
||||||
|
background: #eee;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.red-ui-search-result-node-output{
|
||||||
|
left: 16px;
|
||||||
}
|
}
|
||||||
.palette_icon_container {
|
.palette_icon_container {
|
||||||
width: 18px;
|
width: 18px;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
@import "jquery";
|
@import "jquery";
|
||||||
@import "bootstrap";
|
@import "bootstrap";
|
||||||
|
@import "ace";
|
||||||
|
|
||||||
@import "dropdownMenu";
|
@import "dropdownMenu";
|
||||||
|
|
||||||
|
@ -69,6 +69,9 @@
|
|||||||
margin-right:4px;
|
margin-right:4px;
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
&.fa-ellipsis-h {
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&.disabled {
|
&.disabled {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
@ -95,6 +98,19 @@
|
|||||||
background: $typedInput-button-background-active;
|
background: $typedInput-button-background-active;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
&.red-ui-typedInput-full-width {
|
||||||
|
width: 100%;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button.red-ui-typedInput-option-expand {
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.red-ui-typedInput-option-trigger {
|
button.red-ui-typedInput-option-trigger {
|
||||||
|
@ -87,19 +87,28 @@
|
|||||||
|
|
||||||
<div id="node-dialog-confirm-deploy" class="hide">
|
<div id="node-dialog-confirm-deploy" class="hide">
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div id="node-dialog-confirm-deploy-config" style="text-align: left; padding-top: 30px;" data-i18n="[prepend]deploy.confirm.improperlyConfigured;[append]deploy.confirm.confirm">
|
<div id="node-dialog-confirm-deploy-config" class="node-dialog-confirm-row" data-i18n="[prepend]deploy.confirm.improperlyConfigured;[append]deploy.confirm.confirm">
|
||||||
<ul style="font-size: 0.9em; width: 400px; margin: 10px auto; text-align: left;" id="node-dialog-confirm-deploy-invalid-list"></ul>
|
<ul id="node-dialog-confirm-deploy-invalid-list"></ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="node-dialog-confirm-deploy-unknown" style="text-align: left; padding-top: 10px;" data-i18n="[prepend]deploy.confirm.unknown;[append]deploy.confirm.confirm">
|
<div id="node-dialog-confirm-deploy-unknown" class="node-dialog-confirm-row" data-i18n="[prepend]deploy.confirm.unknown;[append]deploy.confirm.confirm">
|
||||||
<ul style="font-size: 0.9em; width: 400px; margin: 10px auto; text-align: left;" id="node-dialog-confirm-deploy-unknown-list"></ul>
|
<ul id="node-dialog-confirm-deploy-unknown-list"></ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="node-dialog-confirm-deploy-conflict" style="text-align: left; padding-top: 10px;" data-i18n="[prepend]deploy.confirm.conflict;[append]deploy.confirm.confirm">
|
<div id="node-dialog-confirm-deploy-conflict" class="node-dialog-confirm-row">
|
||||||
|
<div style="margin-left: 40px; margin-bottom: 10px;">
|
||||||
|
<span data-i18n="deploy.confirm.conflict"></span>
|
||||||
|
</div>
|
||||||
|
<div id="node-dialog-confirm-deploy-conflict-checking" class="node-dialog-confirm-conflict-row">
|
||||||
|
<img src="red/images/spin.svg"/><div data-i18n="deploy.confirm.conflictChecking"></div>
|
||||||
|
</div>
|
||||||
|
<div id="node-dialog-confirm-deploy-conflict-auto-merge" class="node-dialog-confirm-conflict-row">
|
||||||
|
<i style="color: #3a3;" class="fa fa-check"></i><div data-i18n="deploy.confirm.conflictAutoMerge"></div>
|
||||||
|
</div>
|
||||||
|
<div id="node-dialog-confirm-deploy-conflict-manual-merge" class="node-dialog-confirm-conflict-row">
|
||||||
|
<i style="color: #999;" class="fa fa-exclamation"></i><div data-i18n="deploy.confirm.conflictManualMerge"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="node-dialog-view-diff" class="hide">
|
|
||||||
<ol id="node-dialog-view-diff-diff"></ol>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="node-dialog-library-save-confirm" class="hide">
|
<div id="node-dialog-library-save-confirm" class="hide">
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
@ -159,7 +168,21 @@
|
|||||||
<div class="form-row form-tips" id="subflow-dialog-user-count"></div>
|
<div class="form-row form-tips" id="subflow-dialog-user-count"></div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-red" data-template-name="_expression">
|
||||||
|
<div class="form-row node-text-editor-row">
|
||||||
|
<div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-expression"></div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-expression-func" data-i18n="expressionEditor.functions"></label>
|
||||||
|
<select id="node-input-expression-func"></select>
|
||||||
|
<button id="node-input-expression-func-insert" class="editor-button" data-i18n="expressionEditor.insert"></button>
|
||||||
|
<div style="min-height: 200px;" id="node-input-expression-help"></div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<script src="vendor/vendor.js"></script>
|
<script src="vendor/vendor.js"></script>
|
||||||
|
<script src="vendor/jsonata/jsonata.min.js"></script>
|
||||||
<script src="vendor/ace/ace.js"></script>
|
<script src="vendor/ace/ace.js"></script>
|
||||||
<script src="vendor/ace/ext-language_tools.js"></script>
|
<script src="vendor/ace/ext-language_tools.js"></script>
|
||||||
<script src="{{ asset.red }}"></script>
|
<script src="{{ asset.red }}"></script>
|
||||||
|
147
editor/vendor/jsonata/formatter.js
vendored
Normal file
147
editor/vendor/jsonata/formatter.js
vendored
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
(function() {
|
||||||
|
function indentLine(str,length) {
|
||||||
|
if (length <= 0) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
var i = (new Array(length)).join(" ");
|
||||||
|
str = str.replace(/^\s*/,i);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
function formatExpression(str) {
|
||||||
|
var length = str.length;
|
||||||
|
var start = 0;
|
||||||
|
var inString = false;
|
||||||
|
var inBox = false;
|
||||||
|
var quoteChar;
|
||||||
|
var list = [];
|
||||||
|
var stack = [];
|
||||||
|
var frame;
|
||||||
|
var v;
|
||||||
|
var matchingBrackets = {
|
||||||
|
"(":")",
|
||||||
|
"[":"]",
|
||||||
|
"{":"}"
|
||||||
|
}
|
||||||
|
for (var i=0;i<length;i++) {
|
||||||
|
var c = str[i];
|
||||||
|
if (!inString) {
|
||||||
|
if (c === "'" || c === '"') {
|
||||||
|
inString = true;
|
||||||
|
quoteChar = c;
|
||||||
|
frame = {type:"string",pos:i};
|
||||||
|
list.push(frame);
|
||||||
|
stack.push(frame);
|
||||||
|
} else if (c === ";") {
|
||||||
|
frame = {type:";",pos:i};
|
||||||
|
list.push(frame);
|
||||||
|
} else if (c === ",") {
|
||||||
|
frame = {type:",",pos:i};
|
||||||
|
list.push(frame);
|
||||||
|
} else if (/[\(\[\{]/.test(c)) {
|
||||||
|
frame = {type:"open-block",char:c,pos:i};
|
||||||
|
list.push(frame);
|
||||||
|
stack.push(frame);
|
||||||
|
} else if (/[\}\)\]]/.test(c)) {
|
||||||
|
var oldFrame = stack.pop();
|
||||||
|
if (matchingBrackets[oldFrame.char] !== c) {
|
||||||
|
//console.log("Stack frame mismatch",c,"at",i,"expected",matchingBrackets[oldFrame.char],"from",oldFrame.pos);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
//console.log("Closing",c,"at",i,"compare",oldFrame.type,oldFrame.pos);
|
||||||
|
oldFrame.width = i-oldFrame.pos;
|
||||||
|
frame = {type:"close-block",pos:i,char:c,width:oldFrame.width}
|
||||||
|
list.push(frame);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (c === quoteChar) {
|
||||||
|
// Next char must be a ]
|
||||||
|
inString = false;
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// console.log(stack);
|
||||||
|
var result = str;
|
||||||
|
var indent = 0;
|
||||||
|
var offset = 0;
|
||||||
|
var pre,post,indented;
|
||||||
|
var longStack = [];
|
||||||
|
list.forEach(function(f) {
|
||||||
|
if (f.type === ";" || f.type === ",") {
|
||||||
|
if (longStack[longStack.length-1]) {
|
||||||
|
pre = result.substring(0,offset+f.pos+1);
|
||||||
|
post = result.substring(offset+f.pos+1);
|
||||||
|
indented = indentLine(post,indent);
|
||||||
|
result = pre+"\n"+indented;
|
||||||
|
offset += indented.length-post.length+1;
|
||||||
|
}
|
||||||
|
} else if (f.type === "open-block") {
|
||||||
|
if (f.width > 30) {
|
||||||
|
longStack.push(true);
|
||||||
|
indent += 4;
|
||||||
|
pre = result.substring(0,offset+f.pos+1);
|
||||||
|
post = result.substring(offset+f.pos+1);
|
||||||
|
indented = indentLine(post,indent);
|
||||||
|
result = pre+"\n"+indented;
|
||||||
|
offset += indented.length-post.length+1;
|
||||||
|
} else {
|
||||||
|
longStack.push(false);
|
||||||
|
}
|
||||||
|
} else if (f.type === "close-block") {
|
||||||
|
if (f.width > 30) {
|
||||||
|
indent -= 4;
|
||||||
|
pre = result.substring(0,offset+f.pos);
|
||||||
|
post = result.substring(offset+f.pos);
|
||||||
|
indented = indentLine(post,indent);
|
||||||
|
result = pre+"\n"+indented;
|
||||||
|
offset += indented.length-post.length+1;
|
||||||
|
}
|
||||||
|
longStack.pop();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//console.log(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonata.format = formatExpression;
|
||||||
|
jsonata.functions =
|
||||||
|
{
|
||||||
|
'$append':{ args:['array','array'] },
|
||||||
|
'$average':{ args:['value'] },
|
||||||
|
'$boolean':{ args:['value'] },
|
||||||
|
'$count':{ args:['array'] },
|
||||||
|
'$exists':{ args:['value'] },
|
||||||
|
'$join':{ args:['array','separator'] },
|
||||||
|
'$keys':{ args:['object'] },
|
||||||
|
'$length':{ args:['string'] },
|
||||||
|
'$lookup':{ args:['object','key'] },
|
||||||
|
'$lowercase':{ args:['string'] },
|
||||||
|
'$map':{ args:[] },
|
||||||
|
'$max':{ args:['array'] },
|
||||||
|
'$min':{ args:['array'] },
|
||||||
|
'$not':{ args:['value'] },
|
||||||
|
'$number':{ args:['value'] },
|
||||||
|
'$reduce':{ args:[] },
|
||||||
|
'$split':{ args:['string','separator','limit'] },
|
||||||
|
'$spread':{ args:['object'] },
|
||||||
|
'$string':{ args:['value'] },
|
||||||
|
'$substring':{ args:['string','start','length'] },
|
||||||
|
'$substringAfter':{ args:['string','chars'] },
|
||||||
|
'$substringBefore':{ args:['string','chars'] },
|
||||||
|
'$sum':{ args:['array'] },
|
||||||
|
'$uppercase':{ args:['string'] }
|
||||||
|
}
|
||||||
|
jsonata.getFunctionSnippet = function(fn) {
|
||||||
|
var snippetText = "";
|
||||||
|
if (jsonata.functions.hasOwnProperty(fn)) {
|
||||||
|
var def = jsonata.functions[fn];
|
||||||
|
snippetText = "\\"+fn+"(";
|
||||||
|
if (def.args) {
|
||||||
|
snippetText += def.args.map(function(a,i) { return "${"+(i+1)+":"+a+"}"}).join(", ");
|
||||||
|
}
|
||||||
|
snippetText += ")\n"
|
||||||
|
}
|
||||||
|
return snippetText;
|
||||||
|
}
|
||||||
|
})();
|
134
editor/vendor/jsonata/mode-jsonata.js
vendored
Normal file
134
editor/vendor/jsonata/mode-jsonata.js
vendored
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/worker/worker_client","ace/mode/text"], function(require, exports, module) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var oop = require("../lib/oop");
|
||||||
|
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
|
||||||
|
|
||||||
|
var WorkerClient = require("../worker/worker_client").WorkerClient;
|
||||||
|
var jsonataFunctions = Object.keys(jsonata.functions);
|
||||||
|
// sort in length order (long->short) otherwise substringAfter gets matched
|
||||||
|
// as substring etc.
|
||||||
|
jsonataFunctions.sort(function(A,B) {
|
||||||
|
return B.length-A.length;
|
||||||
|
});
|
||||||
|
jsonataFunctions = jsonataFunctions.join("|").replace(/\$/g,"\\$");
|
||||||
|
|
||||||
|
var JSONataHighlightRules = function() {
|
||||||
|
|
||||||
|
var keywordMapper = this.createKeywordMapper({
|
||||||
|
"keyword.operator":
|
||||||
|
"and|or|in",
|
||||||
|
"constant.language":
|
||||||
|
"null|Infinity|NaN|undefined",
|
||||||
|
"constant.language.boolean":
|
||||||
|
"true|false",
|
||||||
|
"storage.type":
|
||||||
|
"function"
|
||||||
|
}, "identifier");
|
||||||
|
this.$rules = {
|
||||||
|
"start" : [
|
||||||
|
{
|
||||||
|
token : "string",
|
||||||
|
regex : "'(?=.)",
|
||||||
|
next : "qstring"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : "string",
|
||||||
|
regex : '"(?=.)',
|
||||||
|
next : "qqstring"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : "constant.numeric", // hex
|
||||||
|
regex : /0(?:[xX][0-9a-fA-F]+|[bB][01]+)\b/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : "constant.numeric", // float
|
||||||
|
regex : /[+-]?\d[\d_]*(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/
|
||||||
|
},
|
||||||
|
{ token: "keyword",
|
||||||
|
regex: /λ/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "keyword",
|
||||||
|
regex: jsonataFunctions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : keywordMapper,
|
||||||
|
regex : "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : "punctuation.operator",
|
||||||
|
regex : /[.](?![.])/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : "keyword.operator",
|
||||||
|
regex : /\|\||<=|>=|\.\.|\*\*|!=|:=|[=<>`!$%&*+\-~\/^]/,
|
||||||
|
next : "start"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : "punctuation.operator",
|
||||||
|
regex : /[?:,;.]/,
|
||||||
|
next : "start"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : "paren.lparen",
|
||||||
|
regex : /[\[({]/,
|
||||||
|
next : "start"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token : "paren.rparen",
|
||||||
|
regex : /[\])}]/
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"qqstring" : [
|
||||||
|
{
|
||||||
|
token : "string",
|
||||||
|
regex : '"|$',
|
||||||
|
next : "start"
|
||||||
|
}, {
|
||||||
|
defaultToken: "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"qstring" : [
|
||||||
|
{
|
||||||
|
token : "string",
|
||||||
|
regex : "'|$",
|
||||||
|
next : "start"
|
||||||
|
}, {
|
||||||
|
defaultToken: "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
oop.inherits(JSONataHighlightRules, TextHighlightRules);
|
||||||
|
|
||||||
|
var TextMode = require("./text").Mode;
|
||||||
|
var Mode = function() {
|
||||||
|
this.HighlightRules = JSONataHighlightRules;
|
||||||
|
};
|
||||||
|
oop.inherits(Mode, TextMode);
|
||||||
|
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
this.createWorker = function(session) {
|
||||||
|
var worker = new WorkerClient(["ace"], "ace/mode/jsonata_worker", "JSONataWorker");
|
||||||
|
worker.attachToDocument(session.getDocument());
|
||||||
|
|
||||||
|
worker.on("annotate", function(e) {
|
||||||
|
session.setAnnotations(e.data);
|
||||||
|
});
|
||||||
|
|
||||||
|
worker.on("terminate", function() {
|
||||||
|
session.clearAnnotations();
|
||||||
|
});
|
||||||
|
|
||||||
|
return worker;
|
||||||
|
};
|
||||||
|
this.$id = "ace/mode/jsonata";
|
||||||
|
}).call(Mode.prototype);
|
||||||
|
|
||||||
|
exports.Mode = Mode;
|
||||||
|
|
||||||
|
});
|
11
editor/vendor/jsonata/snippets-jsonata.js
vendored
Normal file
11
editor/vendor/jsonata/snippets-jsonata.js
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
define("ace/snippets/jsonata",["require","exports","module"], function(require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
var snippetText = "";
|
||||||
|
for (var fn in jsonata.functions) {
|
||||||
|
if (jsonata.functions.hasOwnProperty(fn)) {
|
||||||
|
snippetText += "# "+fn+"\nsnippet "+fn+"\n\t"+jsonata.getFunctionSnippet(fn)+"\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.snippetText = snippetText;
|
||||||
|
exports.scope = "jsonata";
|
||||||
|
});
|
4236
editor/vendor/jsonata/worker-jsonata.js
vendored
Normal file
4236
editor/vendor/jsonata/worker-jsonata.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -41,7 +41,7 @@
|
|||||||
<p>The button to the right of the node will toggle its output on and off so you can de-clutter the debug window.</p>
|
<p>The button to the right of the node will toggle its output on and off so you can de-clutter the debug window.</p>
|
||||||
<p>If the payload is an object or buffer it will be stringified first for display and indicate that by saying "(Object)" or "(Buffer)".</p>
|
<p>If the payload is an object or buffer it will be stringified first for display and indicate that by saying "(Object)" or "(Buffer)".</p>
|
||||||
<p>Selecting any particular message will highlight (in red) the debug node that reported it. This is useful if you wire up multiple debug nodes.</p>
|
<p>Selecting any particular message will highlight (in red) the debug node that reported it. This is useful if you wire up multiple debug nodes.</p>
|
||||||
<p>Optionally can show the complete <code>msg</code> object, and send messages to the console log.</p>
|
<p>Optionally can show the complete <code>msg</code> object, and send messages to the console log (⇶).</p>
|
||||||
<p>In addition any calls to node.warn or node.error will appear here.</p>
|
<p>In addition any calls to node.warn or node.error will appear here.</p>
|
||||||
</script>
|
</script>
|
||||||
<script src="debug/view/debug-utils.js"></script>
|
<script src="debug/view/debug-utils.js"></script>
|
||||||
@ -58,10 +58,12 @@
|
|||||||
complete: {value:"false", required:true}
|
complete: {value:"false", required:true}
|
||||||
},
|
},
|
||||||
label: function() {
|
label: function() {
|
||||||
|
var suffix = "";
|
||||||
|
if (this.console === true || this.console === "true") { suffix = " ⇶"; }
|
||||||
if (this.complete === true || this.complete === "true") {
|
if (this.complete === true || this.complete === "true") {
|
||||||
return this.name||"msg";
|
return (this.name||"msg") + suffix;
|
||||||
} else {
|
} else {
|
||||||
return this.name || "msg." + ((!this.complete || this.complete === "false") ? "payload" : this.complete);
|
return (this.name || "msg." + ((!this.complete || this.complete === "false") ? "payload" : this.complete)) + suffix;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
@ -144,8 +146,7 @@
|
|||||||
toolbar: uiComponents.footer,
|
toolbar: uiComponents.footer,
|
||||||
enableOnEdit: true
|
enableOnEdit: true
|
||||||
});
|
});
|
||||||
|
RED.actions.add("core:show-debug-tab",function() { RED.sidebar.show('debug')});
|
||||||
|
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
RED._debug = function(msg) {
|
RED._debug = function(msg) {
|
||||||
@ -184,9 +185,10 @@
|
|||||||
RED.comms.subscribe("debug",this.handleDebugMessage);
|
RED.comms.subscribe("debug",this.handleDebugMessage);
|
||||||
|
|
||||||
RED.events.on("workspace:change", this.refreshMessageList);
|
RED.events.on("workspace:change", this.refreshMessageList);
|
||||||
|
|
||||||
$("#debug-tab-open").click(function(e) {
|
$("#debug-tab-open").click(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
subWindow = window.open(document.location.toString().replace(/#.*$/,"")+"debug/view/view.html","nodeREDDebugView","menubar=no,location=no,toolbar=no,chrome,height=500,width=600");
|
subWindow = window.open(document.location.toString().replace(/[?#].*$/,"")+"debug/view/view.html"+document.location.search,"nodeREDDebugView","menubar=no,location=no,toolbar=no,chrome,height=500,width=600");
|
||||||
subWindow.onload = function() {
|
subWindow.onload = function() {
|
||||||
subWindow.postMessage({event:"workspaceChange",activeWorkspace:RED.workspaces.active()},"*");
|
subWindow.postMessage({event:"workspaceChange",activeWorkspace:RED.workspaces.active()},"*");
|
||||||
}
|
}
|
||||||
@ -221,6 +223,8 @@
|
|||||||
RED.sidebar.removeTab("debug");
|
RED.sidebar.removeTab("debug");
|
||||||
RED.events.off("workspace:change", this.refreshMessageList);
|
RED.events.off("workspace:change", this.refreshMessageList);
|
||||||
window.removeEventListener("message",this.handleWindowMessage);
|
window.removeEventListener("message",this.handleWindowMessage);
|
||||||
|
RED.actions.remove("core:show-debug");
|
||||||
|
|
||||||
delete RED._debug;
|
delete RED._debug;
|
||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
|
@ -19,6 +19,7 @@ module.exports = function(RED) {
|
|||||||
var util = require("util");
|
var util = require("util");
|
||||||
var events = require("events");
|
var events = require("events");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
|
var safeJSONStringify = require("json-stringify-safe");
|
||||||
var debuglength = RED.settings.debugMaxLength||1000;
|
var debuglength = RED.settings.debugMaxLength||1000;
|
||||||
var useColors = false;
|
var useColors = false;
|
||||||
// util.inspect.styles.boolean = "red";
|
// util.inspect.styles.boolean = "red";
|
||||||
@ -87,6 +88,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
} else if (msg.msg && typeof msg.msg === 'object') {
|
} else if (msg.msg && typeof msg.msg === 'object') {
|
||||||
var seen = [];
|
var seen = [];
|
||||||
|
var seenAts = [];
|
||||||
try {
|
try {
|
||||||
msg.format = msg.msg.constructor.name || "Object";
|
msg.format = msg.msg.constructor.name || "Object";
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@ -106,7 +108,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isArray || (msg.format === "Object")) {
|
if (isArray || (msg.format === "Object")) {
|
||||||
msg.msg = JSON.stringify(msg.msg, function(key, value) {
|
msg.msg = safeJSONStringify(msg.msg, function(key, value) {
|
||||||
if (key[0] === '_' && key !== "_msgid") {
|
if (key[0] === '_' && key !== "_msgid") {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -118,15 +120,12 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
if (util.isArray(value) && value.length > debuglength) {
|
if (util.isArray(value) && value.length > debuglength) {
|
||||||
value = {
|
value = {
|
||||||
|
__encoded__: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
data: value.slice(0,debuglength),
|
data: value.slice(0,debuglength),
|
||||||
length: value.length
|
length: value.length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typeof value === 'object' && value !== null) {
|
|
||||||
if (seen.indexOf(value) !== -1) { return "[circular]"; }
|
|
||||||
seen.push(value);
|
|
||||||
}
|
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
if (value.length > debuglength) {
|
if (value.length > debuglength) {
|
||||||
return value.substring(0,debuglength)+"...";
|
return value.substring(0,debuglength)+"...";
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
}</pre>
|
}</pre>
|
||||||
<p>The resulting property will be:
|
<p>The resulting property will be:
|
||||||
<pre>Hello Fred. Today is Monday</pre>
|
<pre>Hello Fred. Today is Monday</pre>
|
||||||
|
<p>It is possible to use property from flow context or global context. Just use <code>{{flow.name}}</code> or <code>{{global.name}}</code>.
|
||||||
<p>By default, mustache will escape any HTML entities in the values it substitutes.
|
<p>By default, mustache will escape any HTML entities in the values it substitutes.
|
||||||
To prevent this, use <code>{{{triple}}}</code> braces.
|
To prevent this, use <code>{{{triple}}}</code> braces.
|
||||||
</script>
|
</script>
|
||||||
|
@ -18,6 +18,39 @@ module.exports = function(RED) {
|
|||||||
"use strict";
|
"use strict";
|
||||||
var mustache = require("mustache");
|
var mustache = require("mustache");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom Mustache Context capable to resolve message property and node
|
||||||
|
* flow and global context
|
||||||
|
*/
|
||||||
|
function NodeContext(msg, nodeContext) {
|
||||||
|
this.msgContext = new mustache.Context(msg);
|
||||||
|
this.nodeContext = nodeContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeContext.prototype = new mustache.Context();
|
||||||
|
|
||||||
|
NodeContext.prototype.lookup = function (name) {
|
||||||
|
// try message first:
|
||||||
|
var value = this.msgContext.lookup(name);
|
||||||
|
if (value !== undefined) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try node context:
|
||||||
|
var dot = name.indexOf(".");
|
||||||
|
if (dot > 0) {
|
||||||
|
var contextName = name.substr(0, dot);
|
||||||
|
var variableName = name.substr(dot + 1);
|
||||||
|
|
||||||
|
if (contextName === "flow" && this.nodeContext.flow) {
|
||||||
|
return this.nodeContext.flow.get(variableName);
|
||||||
|
}
|
||||||
|
else if (contextName === "global" && this.nodeContext.global) {
|
||||||
|
return this.nodeContext.global.get(variableName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function TemplateNode(n) {
|
function TemplateNode(n) {
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
this.name = n.name;
|
this.name = n.name;
|
||||||
@ -31,7 +64,7 @@ module.exports = function(RED) {
|
|||||||
try {
|
try {
|
||||||
var value;
|
var value;
|
||||||
if (node.syntax === "mustache") {
|
if (node.syntax === "mustache") {
|
||||||
value = mustache.render(node.template,msg);
|
value = mustache.render(node.template, new NodeContext(msg, node.context()));
|
||||||
} else {
|
} else {
|
||||||
value = node.template;
|
value = node.template;
|
||||||
}
|
}
|
||||||
|
@ -198,20 +198,21 @@ RED.debug = (function() {
|
|||||||
var name = sanitize(((o.name?o.name:o.id)||"").toString());
|
var name = sanitize(((o.name?o.name:o.id)||"").toString());
|
||||||
var topic = sanitize((o.topic||"").toString());
|
var topic = sanitize((o.topic||"").toString());
|
||||||
var property = sanitize(o.property?o.property:'');
|
var property = sanitize(o.property?o.property:'');
|
||||||
var payload = sanitize((o.msg||"").toString());
|
var payload = o.msg;
|
||||||
var format = sanitize((o.format||"").toString());
|
var format = sanitize((o.format||"").toString());
|
||||||
msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'') +
|
msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'') +
|
||||||
((sourceNode&&sourceNode.z)?((" debug-message-flow-"+sourceNode.z+((filter&&(activeWorkspace!==sourceNode.z))?" hide":""))):"");
|
((sourceNode&&sourceNode.z)?((" debug-message-flow-"+sourceNode.z+((filter&&(activeWorkspace!==sourceNode.z))?" hide":""))):"");
|
||||||
$('<span class="debug-message-date">'+ getTimestamp()+'</span>').appendTo(msg);
|
var metaRow = $('<div class="debug-message-meta"></div>').appendTo(msg);
|
||||||
|
$('<span class="debug-message-date">'+ getTimestamp()+'</span>').appendTo(metaRow);
|
||||||
if (sourceNode) {
|
if (sourceNode) {
|
||||||
$('<a>',{href:"#",class:"debug-message-name"}).html('node: '+sourceNode.id)
|
$('<a>',{href:"#",class:"debug-message-name"}).html('node: '+sourceNode.id)
|
||||||
.appendTo(msg)
|
.appendTo(metaRow)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
config.messageSourceClick(sourceNode.id);
|
config.messageSourceClick(sourceNode.id);
|
||||||
});
|
});
|
||||||
} else if (name) {
|
} else if (name) {
|
||||||
$('<span class="debug-message-name">'+name+'</span>').appendTo(msg);
|
$('<span class="debug-message-name">'+name+'</span>').appendTo(metaRow);
|
||||||
}
|
}
|
||||||
// NOTE: relying on function error to have a "type" that all other msgs don't
|
// NOTE: relying on function error to have a "type" that all other msgs don't
|
||||||
if (o.hasOwnProperty("type") && (o.type === "function")) {
|
if (o.hasOwnProperty("type") && (o.type === "function")) {
|
||||||
@ -222,12 +223,12 @@ RED.debug = (function() {
|
|||||||
errorLvlType = 'warn';
|
errorLvlType = 'warn';
|
||||||
}
|
}
|
||||||
$(msg).addClass('debug-message-level-' + errorLvl);
|
$(msg).addClass('debug-message-level-' + errorLvl);
|
||||||
$('<span class="debug-message-topic">function : (' + errorLvlType + ')</span>').appendTo(msg);
|
$('<span class="debug-message-topic">function : (' + errorLvlType + ')</span>').appendTo(metaRow);
|
||||||
} else {
|
} else {
|
||||||
$('<span class="debug-message-topic">'+
|
$('<span class="debug-message-topic">'+
|
||||||
(o.topic?topic+' : ':'')+
|
(o.topic?topic+' : ':'')+
|
||||||
(o.property?'msg.'+property:'msg')+" : "+format+
|
(o.property?'msg.'+property:'msg')+" : "+format+
|
||||||
'</span>').appendTo(msg);
|
'</span>').appendTo(metaRow);
|
||||||
}
|
}
|
||||||
if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number'||/error/i.test(format) ) {
|
if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number'||/error/i.test(format) ) {
|
||||||
payload = JSON.parse(payload);
|
payload = JSON.parse(payload);
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
<li><code>payload</code> is the body of the response</li>
|
<li><code>payload</code> is the body of the response</li>
|
||||||
<li><code>statusCode</code> is the status code of the response, or the error code if the request could not be completed</li>
|
<li><code>statusCode</code> is the status code of the response, or the error code if the request could not be completed</li>
|
||||||
<li><code>headers</code> is an object containing the response headers</li>
|
<li><code>headers</code> is an object containing the response headers</li>
|
||||||
|
<li><code>responseUrl</code> is the url of the server that responds</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p><b>Note</b>: If you need to configure a proxy please add <b>http_proxy=...</b> to your environment variables and restart Node-RED.</p>
|
<p><b>Note</b>: If you need to configure a proxy please add <b>http_proxy=...</b> to your environment variables and restart Node-RED.</p>
|
||||||
</script>
|
</script>
|
||||||
|
@ -159,6 +159,7 @@ module.exports = function(RED) {
|
|||||||
(node.ret === "bin") ? res.setEncoding('binary') : res.setEncoding('utf8');
|
(node.ret === "bin") ? res.setEncoding('binary') : res.setEncoding('utf8');
|
||||||
msg.statusCode = res.statusCode;
|
msg.statusCode = res.statusCode;
|
||||||
msg.headers = res.headers;
|
msg.headers = res.headers;
|
||||||
|
msg.responseUrl = res.responseUrl;
|
||||||
msg.payload = "";
|
msg.payload = "";
|
||||||
// msg.url = url; // revert when warning above finally removed
|
// msg.url = url; // revert when warning above finally removed
|
||||||
res.on('data',function(chunk) {
|
res.on('data',function(chunk) {
|
||||||
|
@ -502,6 +502,9 @@
|
|||||||
"null":"is null",
|
"null":"is null",
|
||||||
"nnull":"is not null",
|
"nnull":"is not null",
|
||||||
"else":"otherwise"
|
"else":"otherwise"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"invalid-expr": "Invalid expression: __error__"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"change": {
|
"change": {
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
var node = this;
|
var node = this;
|
||||||
var previousValueType = {value:"prev",label:this._("inject.previous"),hasValue:false};
|
var previousValueType = {value:"prev",label:this._("inject.previous"),hasValue:false};
|
||||||
|
|
||||||
$("#node-input-property").typedInput({default:this.propertyType||'msg',types:['msg','flow','global']});
|
$("#node-input-property").typedInput({default:this.propertyType||'msg',types:['msg','flow','global','jsonata']});
|
||||||
var operators = [
|
var operators = [
|
||||||
{v:"eq",t:"=="},
|
{v:"eq",t:"=="},
|
||||||
{v:"neq",t:"!="},
|
{v:"neq",t:"!="},
|
||||||
@ -129,10 +129,10 @@
|
|||||||
for (var d in operators) {
|
for (var d in operators) {
|
||||||
selectField.append($("<option></option>").val(operators[d].v).text(operators[d].t));
|
selectField.append($("<option></option>").val(operators[d].v).text(operators[d].t));
|
||||||
}
|
}
|
||||||
var valueField = $('<input/>',{class:"node-input-rule-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num',previousValueType]});
|
var valueField = $('<input/>',{class:"node-input-rule-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata',previousValueType]});
|
||||||
var btwnValueField = $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num',previousValueType]});
|
var btwnValueField = $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata',previousValueType]});
|
||||||
var btwnAndLabel = $('<span/>',{class:"node-input-rule-btwn-label"}).text(" "+andLabel+" ").appendTo(row3);
|
var btwnAndLabel = $('<span/>',{class:"node-input-rule-btwn-label"}).text(" "+andLabel+" ").appendTo(row3);
|
||||||
var btwnValue2Field = $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num',previousValueType]});
|
var btwnValue2Field = $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata',previousValueType]});
|
||||||
var finalspan = $('<span/>',{style:"float: right;margin-top: 6px;"}).appendTo(row);
|
var finalspan = $('<span/>',{style:"float: right;margin-top: 6px;"}).appendTo(row);
|
||||||
finalspan.append(' → <span class="node-input-rule-index">'+(i+1)+'</span> ');
|
finalspan.append(' → <span class="node-input-rule-index">'+(i+1)+'</span> ');
|
||||||
var caseSensitive = $('<input/>',{id:"node-input-rule-case-"+i,class:"node-input-rule-case",type:"checkbox",style:"width:auto;vertical-align:top"}).appendTo(row2);
|
var caseSensitive = $('<input/>',{id:"node-input-rule-case-"+i,class:"node-input-rule-case",type:"checkbox",style:"width:auto;vertical-align:top"}).appendTo(row2);
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var jsonata = require('jsonata');
|
||||||
|
|
||||||
var operators = {
|
var operators = {
|
||||||
'eq': function(a, b) { return a == b; },
|
'eq': function(a, b) { return a == b; },
|
||||||
'neq': function(a, b) { return a != b; },
|
'neq': function(a, b) { return a != b; },
|
||||||
@ -38,9 +41,20 @@ module.exports = function(RED) {
|
|||||||
this.rules = n.rules || [];
|
this.rules = n.rules || [];
|
||||||
this.property = n.property;
|
this.property = n.property;
|
||||||
this.propertyType = n.propertyType || "msg";
|
this.propertyType = n.propertyType || "msg";
|
||||||
|
|
||||||
|
if (this.propertyType === 'jsonata') {
|
||||||
|
try {
|
||||||
|
this.property = jsonata(this.property);
|
||||||
|
} catch(err) {
|
||||||
|
this.error(RED._("switch.errors.invalid-expr",{error:err.message}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.checkall = n.checkall || "true";
|
this.checkall = n.checkall || "true";
|
||||||
this.previousValue = null;
|
this.previousValue = null;
|
||||||
var node = this;
|
var node = this;
|
||||||
|
var valid = true;
|
||||||
for (var i=0; i<this.rules.length; i+=1) {
|
for (var i=0; i<this.rules.length; i+=1) {
|
||||||
var rule = this.rules[i];
|
var rule = this.rules[i];
|
||||||
if (!rule.vt) {
|
if (!rule.vt) {
|
||||||
@ -54,6 +68,13 @@ module.exports = function(RED) {
|
|||||||
if (!isNaN(Number(rule.v))) {
|
if (!isNaN(Number(rule.v))) {
|
||||||
rule.v = Number(rule.v);
|
rule.v = Number(rule.v);
|
||||||
}
|
}
|
||||||
|
} else if (rule.vt === "jsonata") {
|
||||||
|
try {
|
||||||
|
rule.v = jsonata(rule.v);
|
||||||
|
} catch(err) {
|
||||||
|
this.error(RED._("switch.errors.invalid-expr",{error:err.message}));
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (typeof rule.v2 !== 'undefined') {
|
if (typeof rule.v2 !== 'undefined') {
|
||||||
if (!rule.v2t) {
|
if (!rule.v2t) {
|
||||||
@ -65,14 +86,30 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
if (rule.v2t === 'num') {
|
if (rule.v2t === 'num') {
|
||||||
rule.v2 = Number(rule.v2);
|
rule.v2 = Number(rule.v2);
|
||||||
|
} else if (rule.v2t === 'jsonata') {
|
||||||
|
try {
|
||||||
|
rule.v2 = jsonata(rule.v2);
|
||||||
|
} catch(err) {
|
||||||
|
this.error(RED._("switch.errors.invalid-expr",{error:err.message}));
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.on('input', function (msg) {
|
this.on('input', function (msg) {
|
||||||
var onward = [];
|
var onward = [];
|
||||||
try {
|
try {
|
||||||
var prop = RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg);
|
var prop;
|
||||||
|
if (node.propertyType === 'jsonata') {
|
||||||
|
prop = node.property.evaluate({msg:msg});
|
||||||
|
} else {
|
||||||
|
prop = RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg);
|
||||||
|
}
|
||||||
var elseflag = true;
|
var elseflag = true;
|
||||||
for (var i=0; i<node.rules.length; i+=1) {
|
for (var i=0; i<node.rules.length; i+=1) {
|
||||||
var rule = node.rules[i];
|
var rule = node.rules[i];
|
||||||
@ -80,12 +117,26 @@ module.exports = function(RED) {
|
|||||||
var v1,v2;
|
var v1,v2;
|
||||||
if (rule.vt === 'prev') {
|
if (rule.vt === 'prev') {
|
||||||
v1 = node.previousValue;
|
v1 = node.previousValue;
|
||||||
|
} else if (rule.vt === 'jsonata') {
|
||||||
|
try {
|
||||||
|
v1 = rule.v.evaluate({msg:msg});
|
||||||
|
} catch(err) {
|
||||||
|
node.error(RED._("switch.errors.invalid-expr",{error:err.message}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
v1 = RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg);
|
v1 = RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg);
|
||||||
}
|
}
|
||||||
v2 = rule.v2;
|
v2 = rule.v2;
|
||||||
if (rule.v2t === 'prev') {
|
if (rule.v2t === 'prev') {
|
||||||
v2 = node.previousValue;
|
v2 = node.previousValue;
|
||||||
|
} else if (rule.v2t === 'jsonata') {
|
||||||
|
try {
|
||||||
|
v2 = rule.v2.evaluate({msg:msg});
|
||||||
|
} catch(err) {
|
||||||
|
node.error(RED._("switch.errors.invalid-expr",{error:err.message}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if (typeof v2 !== 'undefined') {
|
} else if (typeof v2 !== 'undefined') {
|
||||||
v2 = RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg);
|
v2 = RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg);
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@
|
|||||||
.appendTo(row2);
|
.appendTo(row2);
|
||||||
var propertyValue = $('<input/>',{class:"node-input-rule-property-value",type:"text"})
|
var propertyValue = $('<input/>',{class:"node-input-rule-property-value",type:"text"})
|
||||||
.appendTo(row2)
|
.appendTo(row2)
|
||||||
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','date']});
|
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','date','jsonata']});
|
||||||
|
|
||||||
var row3_1 = $('<div/>').appendTo(row3);
|
var row3_1 = $('<div/>').appendTo(row3);
|
||||||
$('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
|
$('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
var jsonata = require("jsonata");
|
||||||
|
|
||||||
function ChangeNode(n) {
|
function ChangeNode(n) {
|
||||||
RED.nodes.createNode(this, n);
|
RED.nodes.createNode(this, n);
|
||||||
@ -85,6 +86,13 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
} else if (rule.tot === 'bool') {
|
} else if (rule.tot === 'bool') {
|
||||||
rule.to = /^true$/i.test(rule.to);
|
rule.to = /^true$/i.test(rule.to);
|
||||||
|
} else if (rule.tot === 'jsonata') {
|
||||||
|
try {
|
||||||
|
rule.to = jsonata(rule.to);
|
||||||
|
} catch(e) {
|
||||||
|
valid = false;
|
||||||
|
this.error(RED._("change.errors.invalid-from",{error:e.message}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,6 +115,8 @@ module.exports = function(RED) {
|
|||||||
value = node.context().global.get(rule.to);
|
value = node.context().global.get(rule.to);
|
||||||
} else if (rule.tot === 'date') {
|
} else if (rule.tot === 'date') {
|
||||||
value = Date.now();
|
value = Date.now();
|
||||||
|
} else if (rule.tot === 'jsonata') {
|
||||||
|
value = rule.to.evaluate({msg:msg});
|
||||||
}
|
}
|
||||||
if (rule.t === 'change') {
|
if (rule.t === 'change') {
|
||||||
if (rule.fromt === 'msg' || rule.fromt === 'flow' || rule.fromt === 'global') {
|
if (rule.fromt === 'msg' || rule.fromt === 'flow' || rule.fromt === 'global') {
|
||||||
|
@ -45,8 +45,8 @@ module.exports = function(RED) {
|
|||||||
data = new Buffer(data);
|
data = new Buffer(data);
|
||||||
if (this.overwriteFile === "true") {
|
if (this.overwriteFile === "true") {
|
||||||
// using "binary" not {encoding:"binary"} to be 0.8 compatible for a while
|
// using "binary" not {encoding:"binary"} to be 0.8 compatible for a while
|
||||||
fs.writeFile(filename, data, "binary", function (err) {
|
//fs.writeFile(filename, data, "binary", function (err) {
|
||||||
//fs.writeFile(filename, data, {encoding:"binary"}, function (err) {
|
fs.writeFile(filename, data, {encoding:"binary"}, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if ((err.code === "ENOENT") && node.createDir) {
|
if ((err.code === "ENOENT") && node.createDir) {
|
||||||
fs.ensureFile(filename, function (err) {
|
fs.ensureFile(filename, function (err) {
|
||||||
@ -71,8 +71,8 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// using "binary" not {encoding:"binary"} to be 0.8 compatible for a while longer
|
// using "binary" not {encoding:"binary"} to be 0.8 compatible for a while longer
|
||||||
fs.appendFile(filename, data, "binary", function (err) {
|
//fs.appendFile(filename, data, "binary", function (err) {
|
||||||
//fs.appendFile(filename, data, {encoding:"binary"}, function (err) {
|
fs.appendFile(filename, data, {encoding:"binary"}, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if ((err.code === "ENOENT") && node.createDir) {
|
if ((err.code === "ENOENT") && node.createDir) {
|
||||||
fs.ensureFile(filename, function (err) {
|
fs.ensureFile(filename, function (err) {
|
||||||
|
71
package.json
71
package.json
@ -26,36 +26,38 @@
|
|||||||
"editor", "messaging", "iot", "ibm", "flow"
|
"editor", "messaging", "iot", "ibm", "flow"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"basic-auth": "1.0.4",
|
"basic-auth": "1.1.0",
|
||||||
"bcryptjs": "2.3.0",
|
"bcryptjs": "2.4.0",
|
||||||
"body-parser": "1.15.2",
|
"body-parser": "1.15.2",
|
||||||
"cheerio":"0.22.0",
|
"cheerio":"0.22.0",
|
||||||
"clone": "2.0.0",
|
"clone": "2.1.0",
|
||||||
"cookie-parser": "1.4.3",
|
"cookie-parser": "1.4.3",
|
||||||
"cors":"2.8.1",
|
"cors":"2.8.1",
|
||||||
"cron":"1.1.1",
|
"cron":"1.2.1",
|
||||||
"express": "4.14.0",
|
"express": "4.14.0",
|
||||||
"follow-redirects":"0.2.0",
|
"follow-redirects":"1.2.1",
|
||||||
"fs-extra": "0.30.0",
|
"fs-extra": "1.0.0",
|
||||||
"fs.notify":"0.0.4",
|
"fs.notify":"0.0.4",
|
||||||
"i18next":"1.10.6",
|
"i18next":"1.10.6",
|
||||||
"is-utf8":"0.2.1",
|
"is-utf8":"0.2.1",
|
||||||
"js-yaml": "3.6.1",
|
"js-yaml": "3.7.0",
|
||||||
|
"json-stringify-safe":"5.0.1",
|
||||||
|
"jsonata":"1.0.10",
|
||||||
"media-typer": "0.3.0",
|
"media-typer": "0.3.0",
|
||||||
"mqtt": "1.14.1",
|
"mqtt": "1.*",
|
||||||
"mustache": "2.2.1",
|
"mustache": "2.3.0",
|
||||||
"nopt": "3.0.6",
|
"nopt": "3.0.6",
|
||||||
"oauth2orize":"1.5.0",
|
"oauth2orize":"1.6.0",
|
||||||
"on-headers":"1.0.1",
|
"on-headers":"1.0.1",
|
||||||
"passport":"0.3.2",
|
"passport":"0.3.2",
|
||||||
"passport-http-bearer":"1.0.1",
|
"passport-http-bearer":"1.0.1",
|
||||||
"passport-oauth2-client-password":"0.1.2",
|
"passport-oauth2-client-password":"0.1.2",
|
||||||
"raw-body":"2.1.7",
|
"raw-body":"2.1.7",
|
||||||
"semver": "5.3.0",
|
"semver": "5.3.0",
|
||||||
"sentiment":"1.0.6",
|
"sentiment":"2.1.0",
|
||||||
"uglify-js":"2.7.3",
|
"uglify-js":"2.7.5",
|
||||||
"when": "3.7.7",
|
"when": "3.7.7",
|
||||||
"ws": "0.8.1",
|
"ws": "1.1.1",
|
||||||
"xml2js":"0.4.17",
|
"xml2js":"0.4.17",
|
||||||
"node-red-node-feedparser":"0.1.*",
|
"node-red-node-feedparser":"0.1.*",
|
||||||
"node-red-node-email":"0.1.*",
|
"node-red-node-email":"0.1.*",
|
||||||
@ -63,31 +65,30 @@
|
|||||||
"node-red-node-rbe":"0.1.*"
|
"node-red-node-rbe":"0.1.*"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"node-red-node-serialport":"0.4.*",
|
"bcrypt":"~1.0.1"
|
||||||
"bcrypt":"0.8.7"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"grunt": "1.0.1",
|
"grunt": "~1.0.1",
|
||||||
"grunt-chmod": "1.1.1",
|
"grunt-chmod": "~1.1.1",
|
||||||
"grunt-cli": "1.2.0",
|
"grunt-cli": "~1.2.0",
|
||||||
"grunt-concurrent":"2.3.1",
|
"grunt-concurrent":"~2.3.1",
|
||||||
"grunt-contrib-clean":"1.0.0",
|
"grunt-contrib-clean":"~1.0.0",
|
||||||
"grunt-contrib-compress": "1.3.0",
|
"grunt-contrib-compress": "~1.3.0",
|
||||||
"grunt-contrib-concat":"1.0.1",
|
"grunt-contrib-concat":"~1.0.1",
|
||||||
"grunt-contrib-copy": "1.0.0",
|
"grunt-contrib-copy": "~1.0.0",
|
||||||
"grunt-contrib-jshint": "1.0.0",
|
"grunt-contrib-jshint": "~1.1.0",
|
||||||
"grunt-contrib-uglify": "2.0.0",
|
"grunt-contrib-uglify": "~2.0.0",
|
||||||
"grunt-contrib-watch":"1.0.0",
|
"grunt-contrib-watch":"~1.0.0",
|
||||||
"grunt-jsonlint":"1.1.0",
|
"grunt-jsonlint":"~1.1.0",
|
||||||
"grunt-nodemon":"0.4.2",
|
"grunt-nodemon":"~0.4.2",
|
||||||
"grunt-sass":"1.2.1",
|
"grunt-sass":"~1.2.1",
|
||||||
"grunt-simple-mocha": "0.4.1",
|
"grunt-simple-mocha": "~0.4.1",
|
||||||
"mocha": "3.1.1",
|
"mocha": "~3.2.0",
|
||||||
"should": "8.4.0",
|
"should": "^8.4.0",
|
||||||
"sinon": "1.17.6",
|
"sinon": "^1.17.6",
|
||||||
"supertest": "2.0.0"
|
"supertest": "^2.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,9 @@ var lastSentTime;
|
|||||||
function handleStatus(event) {
|
function handleStatus(event) {
|
||||||
publish("status/"+event.id,event.status,true);
|
publish("status/"+event.id,event.status,true);
|
||||||
}
|
}
|
||||||
|
function handleRuntimeEvent(event) {
|
||||||
|
publish("notification/"+event.id,event,true);
|
||||||
|
}
|
||||||
function init(_server,runtime) {
|
function init(_server,runtime) {
|
||||||
server = _server;
|
server = _server;
|
||||||
settings = runtime.settings;
|
settings = runtime.settings;
|
||||||
@ -40,6 +42,9 @@ function init(_server,runtime) {
|
|||||||
|
|
||||||
runtime.events.removeListener("node-status",handleStatus);
|
runtime.events.removeListener("node-status",handleStatus);
|
||||||
runtime.events.on("node-status",handleStatus);
|
runtime.events.on("node-status",handleStatus);
|
||||||
|
|
||||||
|
runtime.events.removeListener("runtime-event",handleRuntimeEvent);
|
||||||
|
runtime.events.on("runtime-event",handleRuntimeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
|
@ -155,7 +155,12 @@ function init(_server,_runtime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function start() {
|
function start() {
|
||||||
return i18n.registerMessageCatalog("editor",path.resolve(path.join(__dirname,"locales")),"editor.json").then(i18n.registerMessageCatalog("infotips",path.resolve(path.join(__dirname,"locales")),"infotips.json")).then(function() {
|
var catalogPath = path.resolve(path.join(__dirname,"locales"));
|
||||||
|
return i18n.registerMessageCatalogs([
|
||||||
|
{namespace: "editor", dir: catalogPath, file:"editor.json"},
|
||||||
|
{namespace: "jsonata", dir: catalogPath, file:"jsonata.json"},
|
||||||
|
{namespace: "infotips", dir: catalogPath, file:"infotips.json"}
|
||||||
|
]).then(function(){
|
||||||
comms.start();
|
comms.start();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,8 @@
|
|||||||
"warning": "<strong>Warning</strong>: __message__",
|
"warning": "<strong>Warning</strong>: __message__",
|
||||||
"warnings": {
|
"warnings": {
|
||||||
"undeployedChanges": "node has undeployed changes",
|
"undeployedChanges": "node has undeployed changes",
|
||||||
"nodeActionDisabled": "node actions disabled within subflow"
|
"nodeActionDisabled": "node actions disabled within subflow",
|
||||||
|
"missing-types": "Flows stopped due to missing node types. Check logs for details."
|
||||||
},
|
},
|
||||||
|
|
||||||
"error": "<strong>Error</strong>: __message__",
|
"error": "<strong>Error</strong>: __message__",
|
||||||
@ -129,9 +130,31 @@
|
|||||||
"improperlyConfigured": "The workspace contains some nodes that are not properly configured:",
|
"improperlyConfigured": "The workspace contains some nodes that are not properly configured:",
|
||||||
"unknown": "The workspace contains some unknown node types:",
|
"unknown": "The workspace contains some unknown node types:",
|
||||||
"confirm": "Are you sure you want to deploy?",
|
"confirm": "Are you sure you want to deploy?",
|
||||||
"conflict": "The server is running a more recent set of flows."
|
"conflict": "The server is running a more recent set of flows.",
|
||||||
|
"conflictChecking": "Checking to see if the changes can be merged automatically",
|
||||||
|
"conflictAutoMerge": "The changes include no conflicts and can be merged automatically.",
|
||||||
|
"conflictManualMerge": "The changes include conflicts that must be resolved before they can be deployed."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"diff": {
|
||||||
|
"unresolvedCount": "__count__ unresolved conflict",
|
||||||
|
"unresolvedCount_plural": "__count__ unresolved conflicts",
|
||||||
|
"type": {
|
||||||
|
"added": "added",
|
||||||
|
"changed": "changed",
|
||||||
|
"unchanged": "unchanged",
|
||||||
|
"deleted": "deleted",
|
||||||
|
"flowDeleted": "flow deleted",
|
||||||
|
"flowAdded": "flow added",
|
||||||
|
"movedTo": "moved to __id__",
|
||||||
|
"movedFrom": "moved from __id__"
|
||||||
|
},
|
||||||
|
"nodeCount": "__count__ node",
|
||||||
|
"nodeCount_plural": "__count__ nodes",
|
||||||
|
"local":"Local",
|
||||||
|
"remote":"Remote"
|
||||||
|
|
||||||
|
},
|
||||||
"subflow": {
|
"subflow": {
|
||||||
"editSubflow": "Edit flow template: __name__",
|
"editSubflow": "Edit flow template: __name__",
|
||||||
"edit": "Edit flow template",
|
"edit": "Edit flow template",
|
||||||
@ -317,6 +340,11 @@
|
|||||||
"add": "add"
|
"add": "add"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"empty": "No matches found"
|
"empty": "No matches found",
|
||||||
|
"addNode": "add a node..."
|
||||||
|
},
|
||||||
|
"expressionEditor": {
|
||||||
|
"functions": "Functions",
|
||||||
|
"insert": "Insert"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
98
red/api/locales/en-US/jsonata.json
Normal file
98
red/api/locales/en-US/jsonata.json
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
"$string": {
|
||||||
|
"args": "arg",
|
||||||
|
"desc": "Casts the *arg* parameter to a string using the following casting rules:\n\n - Strings are unchanged\n - Functions are converted to an empty string\n - Numeric infinity and NaN throw an error because they cannot be represented as a JSON number\n - All other values are converted to a JSON string using the `JSON.stringify` function"
|
||||||
|
},
|
||||||
|
"$length": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "Returns the number of characters in the string `str`. An error is thrown if `str` is not a string."
|
||||||
|
},
|
||||||
|
"$substring": {
|
||||||
|
"args": "str, start[, length]",
|
||||||
|
"desc": "Returns a string containing the characters in the first parameter `str` starting at position `start` (zero-offset). If `length` is specified, then the substring will contain maximum `length` characters. If `start` is negative then it indicates the number of characters from the end of `str`."
|
||||||
|
},
|
||||||
|
"$substringBefore": {
|
||||||
|
"args": "str, chars",
|
||||||
|
"desc": "Returns the substring before the first occurrence of the character sequence chars in `str`. If `str` does not contain `chars`, then it returns `str`."
|
||||||
|
},
|
||||||
|
"$substringAfter": {
|
||||||
|
"args": "str, chars",
|
||||||
|
"desc": "Returns the substring after the first occurrence of the character sequence `chars` in `str`. If `str` does not contain `chars`, then it returns `str`."
|
||||||
|
},
|
||||||
|
"$uppercase": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "Returns a string with all the characters of `str` converted to uppercase."
|
||||||
|
},
|
||||||
|
"$lowercase": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "Returns a string with all the characters of `str` converted to lowercase."
|
||||||
|
},
|
||||||
|
"$split": {
|
||||||
|
"args": "str[, separator][, limit]",
|
||||||
|
"desc": "Splits the `str` parameter into an array of substrings. It is an error if `str` is not a string. The optional `separator` parameter specifies the characters within the `str` about which it should be split. If `separator` is not specified, then the empty string is assumed, and `str` will be split into an array of single characters. It is an error if `separator` is not a string. The optional `limit` parameter is a number that specifies the maximum number of substrings to include in the resultant array. Any additional substrings are discarded. If `limit` is not specified, then `str` is fully split with no limit to the size of the resultant array. It is an error if `limit` is not a non-negative number."
|
||||||
|
},
|
||||||
|
"$join": {
|
||||||
|
"args": "array[, separator]",
|
||||||
|
"desc": "Joins an array of component strings into a single concatenated string with each component string separated by the optional `separator` parameter. It is an error if the input `array` contains an item which isn't a string. If `separator` is not specified, then it is assumed to be the empty string, i.e. no `separator` between the component strings. It is an error if `separator` is not a string."
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
"$number": {
|
||||||
|
"args": "arg",
|
||||||
|
"desc": "Casts the `arg` parameter to a number using the following casting rules:\n\n - Numbers are unchanged\n - Strings that contain a sequence of characters that represent a legal JSON number are converted to that number\n - All other values cause an error to be thrown."
|
||||||
|
},
|
||||||
|
"$sum": {
|
||||||
|
"args": "array",
|
||||||
|
"desc": "Returns the arithmetic sum of an `array` of numbers. It is an error if the input `array` contains an item which isn't a number."
|
||||||
|
},
|
||||||
|
"$max": {
|
||||||
|
"args": "array",
|
||||||
|
"desc": "Returns the maximum number in an `array` of numbers. It is an error if the input `array` contains an item which isn't a number."
|
||||||
|
},
|
||||||
|
"$min": {
|
||||||
|
"args": "array",
|
||||||
|
"desc": "Returns the minimum number in an `array` of numbers. It is an error if the input `array` contains an item which isn't a number."
|
||||||
|
},
|
||||||
|
"$average": {
|
||||||
|
"args": "array",
|
||||||
|
"desc": "Returns the mean value of an `array` of numbers. It is an error if the input `array` contains an item which isn't a number."
|
||||||
|
},
|
||||||
|
"$boolean": {
|
||||||
|
"args": "arg",
|
||||||
|
"desc": "Casts the argument to a Boolean using the following rules:\n\n - `Boolean` : unchanged\n - `string`: empty : `false`\n - `string`: non-empty : `true`\n - `number`: `0` : `false`\n - `number`: non-zero : `true`\n - `null` : `false`\n - `array`: empty : `false`\n - `array`: contains a member that casts to `true` : `true`\n - `array`: all members cast to `false` : `false`\n - `object`: empty : `false`\n - `object`: non-empty : `true`\n - `function` : `false`"
|
||||||
|
},
|
||||||
|
|
||||||
|
"$not": {
|
||||||
|
"args": "arg",
|
||||||
|
"desc": "Returns Boolean NOT on the argument. `arg` is first cast to a boolean"
|
||||||
|
},
|
||||||
|
"$exists": {
|
||||||
|
"args": "arg",
|
||||||
|
"desc": "Returns Boolean `true` if the `arg` expression evaluates to a value, or `false` if the expression does not match anything (e.g. a path to a non-existent field reference)."
|
||||||
|
},
|
||||||
|
"$count": {
|
||||||
|
"args": "array",
|
||||||
|
"desc": "Returns the number of items in the array"
|
||||||
|
},
|
||||||
|
"$append": {
|
||||||
|
"args": "array, array",
|
||||||
|
"desc": "Appends two arrays"
|
||||||
|
},
|
||||||
|
|
||||||
|
"$keys": {
|
||||||
|
"args": "object",
|
||||||
|
"desc": "Returns an array containing the keys in the object. If the argument is an array of objects, then the array returned contains a de-duplicated list of all the keys in all of the objects."
|
||||||
|
},
|
||||||
|
|
||||||
|
"$lookup": {
|
||||||
|
"args": "object, key",
|
||||||
|
"desc": "Returns the value associated with key in object. If the first argument is an array of objects, then all of the objects in the array are searched, and the values associated with all occurrences of key are returned."
|
||||||
|
},
|
||||||
|
|
||||||
|
"$spread": {
|
||||||
|
"args": "object",
|
||||||
|
"desc": "Splits an object containing key/value pairs into an array of objects, each of which has a single key/value pair from the input object. If the parameter is an array of objects, then the resultant array contains an object for every key/value pair in every object in the supplied array."
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -92,7 +92,7 @@ function start() {
|
|||||||
reportMetrics();
|
reportMetrics();
|
||||||
}, settings.runtimeMetricInterval||15000);
|
}, settings.runtimeMetricInterval||15000);
|
||||||
}
|
}
|
||||||
console.log("\n\n"+log._("runtime.welcome")+"\n===================\n");
|
log.info("\n\n"+log._("runtime.welcome")+"\n===================\n");
|
||||||
if (settings.version) {
|
if (settings.version) {
|
||||||
log.info(log._("runtime.version",{component:"Node-RED",version:"v"+settings.version}));
|
log.info(log._("runtime.version",{component:"Node-RED",version:"v"+settings.version}));
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ function init(runtime) {
|
|||||||
log.info(log._("nodes.flows.registered-missing", {type:type}));
|
log.info(log._("nodes.flows.registered-missing", {type:type}));
|
||||||
activeFlowConfig.missingTypes.splice(i,1);
|
activeFlowConfig.missingTypes.splice(i,1);
|
||||||
if (activeFlowConfig.missingTypes.length === 0 && started) {
|
if (activeFlowConfig.missingTypes.length === 0 && started) {
|
||||||
|
events.emit("runtime-event",{id:"runtime-state"});
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,6 +239,7 @@ function start(type,diff,muteLog) {
|
|||||||
log.info(log._("nodes.flows.missing-type-install-2"));
|
log.info(log._("nodes.flows.missing-type-install-2"));
|
||||||
log.info(" "+settings.userDir);
|
log.info(" "+settings.userDir);
|
||||||
}
|
}
|
||||||
|
events.emit("runtime-event",{id:"runtime-state",type:"warning",text:"notification.warnings.missing-types"});
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
}
|
}
|
||||||
if (!muteLog) {
|
if (!muteLog) {
|
||||||
@ -287,6 +289,8 @@ function start(type,diff,muteLog) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
events.emit("nodes-started");
|
events.emit("nodes-started");
|
||||||
|
events.emit("runtime-event",{id:"runtime-state"});
|
||||||
|
|
||||||
if (!muteLog) {
|
if (!muteLog) {
|
||||||
if (diff) {
|
if (diff) {
|
||||||
log.info(log._("nodes.flows.started-modified-"+type));
|
log.info(log._("nodes.flows.started-modified-"+type));
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
var clone = require("clone");
|
var clone = require("clone");
|
||||||
|
var jsonata = require("jsonata");
|
||||||
|
|
||||||
function generateId() {
|
function generateId() {
|
||||||
return (1+Math.random()*4294967295).toString(16);
|
return (1+Math.random()*4294967295).toString(16);
|
||||||
@ -310,6 +311,8 @@ function evaluateNodeProperty(value, type, node, msg) {
|
|||||||
return node.context().global.get(value);
|
return node.context().global.get(value);
|
||||||
} else if (type === 'bool') {
|
} else if (type === 'bool') {
|
||||||
return /^true$/i.test(value);
|
return /^true$/i.test(value);
|
||||||
|
} else if (type === 'jsonata') {
|
||||||
|
return jsonata(value).evaluate({msg:msg});
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ describe('debug node', function() {
|
|||||||
topic:"debug",
|
topic:"debug",
|
||||||
data:{
|
data:{
|
||||||
id:"n1",
|
id:"n1",
|
||||||
msg:'{\n "name": "bar",\n "o": "[circular]"\n}',
|
msg:'{\n "name": "bar",\n "o": "[Circular ~]"\n}',
|
||||||
property:"payload",format:"Object"
|
property:"payload",format:"Object"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -43,6 +43,52 @@ describe('template node', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should modify payload from flow context', function(done) {
|
||||||
|
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow.value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||||
|
helper.load(templateNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n1.context().flow.set("value","foo");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
msg.should.have.property('topic', 'bar');
|
||||||
|
msg.should.have.property('payload', 'payload=foo');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
n1.receive({payload:"foo",topic: "bar"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should modify payload from global context', function(done) {
|
||||||
|
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{global.value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||||
|
helper.load(templateNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n1.context().global.set("value","foo");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
msg.should.have.property('topic', 'bar');
|
||||||
|
msg.should.have.property('payload', 'payload=foo');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
n1.receive({payload:"foo",topic: "bar"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle missing node context', function(done) {
|
||||||
|
// this is artificial test because in flow there is missing z property (probably never happen in real usage)
|
||||||
|
var flow = [{id:"n1",type:"template", field:"payload", template:"payload={{flow.value}},{{global.value}}",wires:[["n2"]]},{id:"n2",type:"helper"}];
|
||||||
|
helper.load(templateNode, flow, function() {
|
||||||
|
var n1 = helper.getNode("n1");
|
||||||
|
var n2 = helper.getNode("n2");
|
||||||
|
n2.on("input", function(msg) {
|
||||||
|
msg.should.have.property('topic', 'bar');
|
||||||
|
msg.should.have.property('payload', 'payload=,');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
n1.receive({payload:"foo",topic: "bar"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should modify payload in plain text mode', function(done) {
|
it('should modify payload in plain text mode', function(done) {
|
||||||
var flow = [{id:"n1", type:"template", field:"payload", syntax:"plain", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",type:"helper"}];
|
var flow = [{id:"n1", type:"template", field:"payload", syntax:"plain", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",type:"helper"}];
|
||||||
helper.load(templateNode, flow, function() {
|
helper.load(templateNode, flow, function() {
|
||||||
@ -57,32 +103,36 @@ describe('template node', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
xit('should modify flow context', function(done) {
|
it('should modify flow context', function(done) {
|
||||||
var flow = [{id:"n1", type:"template", field:"payload", fieldType:"flow", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",type:"helper"}];
|
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", fieldType:"flow", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||||
helper.load(templateNode, flow, function() {
|
helper.load(templateNode, flow, function() {
|
||||||
var n1 = helper.getNode("n1");
|
var n1 = helper.getNode("n1");
|
||||||
var n2 = helper.getNode("n2");
|
var n2 = helper.getNode("n2");
|
||||||
setTimeout( function() {
|
n2.on("input", function(msg) {
|
||||||
console.log(n2);
|
// mesage is intact
|
||||||
console.log(n2.context().global.get("payload"));
|
msg.should.have.property('topic', 'bar');
|
||||||
//c.should.equal(1); // should only have had one output.
|
msg.should.have.property('payload', 'foo');
|
||||||
|
// result is in flow context
|
||||||
|
n2.context().flow.get("payload").should.equal("payload=foo");
|
||||||
done();
|
done();
|
||||||
},50);
|
});
|
||||||
n1.receive({payload:"foo",topic: "bar"});
|
n1.receive({payload:"foo",topic: "bar"});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
xit('should modify global context', function(done) {
|
it('should modify global context', function(done) {
|
||||||
var flow = [{id:"n1", type:"template", field:"payload", fieldType:"global", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",type:"helper"}];
|
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", fieldType:"global", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
|
||||||
helper.load(templateNode, flow, function() {
|
helper.load(templateNode, flow, function() {
|
||||||
var n1 = helper.getNode("n1");
|
var n1 = helper.getNode("n1");
|
||||||
var n2 = helper.getNode("n2");
|
var n2 = helper.getNode("n2");
|
||||||
setTimeout( function() {
|
n2.on("input", function(msg) {
|
||||||
console.log(n2);
|
// mesage is intact
|
||||||
console.log(n2.context().global.get("payload"));
|
msg.should.have.property('topic', 'bar');
|
||||||
//c.should.equal(1); // should only have had one output.
|
msg.should.have.property('payload', 'foo');
|
||||||
|
// result is in global context
|
||||||
|
n2.context().global.get("payload").should.equal("payload=foo");
|
||||||
done();
|
done();
|
||||||
},50);
|
});
|
||||||
n1.receive({payload:"foo",topic: "bar"});
|
n1.receive({payload:"foo",topic: "bar"});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user