mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge pull request #2812 from node-red/property-types
Support node property typing
This commit is contained in:
commit
ccfde84769
@ -343,17 +343,29 @@ RED.history = (function() {
|
|||||||
if (ev.changes.hasOwnProperty(i)) {
|
if (ev.changes.hasOwnProperty(i)) {
|
||||||
inverseEv.changes[i] = ev.node[i];
|
inverseEv.changes[i] = ev.node[i];
|
||||||
if (ev.node._def.defaults && ev.node._def.defaults[i] && ev.node._def.defaults[i].type) {
|
if (ev.node._def.defaults && ev.node._def.defaults[i] && ev.node._def.defaults[i].type) {
|
||||||
// This is a config node property
|
// This property is a reference to another node or nodes.
|
||||||
var currentConfigNode = RED.nodes.node(ev.node[i]);
|
var nodeList = ev.node[i];
|
||||||
if (currentConfigNode) {
|
if (!Array.isArray(nodeList)) {
|
||||||
|
nodeList = [nodeList];
|
||||||
|
}
|
||||||
|
nodeList.forEach(function(id) {
|
||||||
|
var currentConfigNode = RED.nodes.node(id);
|
||||||
|
if (currentConfigNode && currentConfigNode._def.category === "config") {
|
||||||
currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1);
|
currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1);
|
||||||
RED.events.emit("nodes:change",currentConfigNode);
|
RED.events.emit("nodes:change",currentConfigNode);
|
||||||
}
|
}
|
||||||
var newConfigNode = RED.nodes.node(ev.changes[i]);
|
});
|
||||||
if (newConfigNode) {
|
nodeList = ev.changes[i];
|
||||||
|
if (!Array.isArray(nodeList)) {
|
||||||
|
nodeList = [nodeList];
|
||||||
|
}
|
||||||
|
nodeList.forEach(function(id) {
|
||||||
|
var newConfigNode = RED.nodes.node(id);
|
||||||
|
if (newConfigNode && newConfigNode._def.category === "config") {
|
||||||
newConfigNode.users.push(ev.node);
|
newConfigNode.users.push(ev.node);
|
||||||
RED.events.emit("nodes:change",newConfigNode);
|
RED.events.emit("nodes:change",newConfigNode);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
ev.node[i] = ev.changes[i];
|
ev.node[i] = ev.changes[i];
|
||||||
}
|
}
|
||||||
|
@ -164,6 +164,21 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
// TODO: too tightly coupled into palette UI
|
// TODO: too tightly coupled into palette UI
|
||||||
}
|
}
|
||||||
|
if (def.defaults) {
|
||||||
|
for (var d in def.defaults) {
|
||||||
|
if (def.defaults.hasOwnProperty(d)) {
|
||||||
|
if (def.defaults[d].type) {
|
||||||
|
try {
|
||||||
|
def.defaults[d]._type = parseNodePropertyTypeString(def.defaults[d].type)
|
||||||
|
} catch(err) {
|
||||||
|
console.warn(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
RED.events.emit("registry:node-type-added",nt);
|
RED.events.emit("registry:node-type-added",nt);
|
||||||
},
|
},
|
||||||
removeNodeType: function(nt) {
|
removeNodeType: function(nt) {
|
||||||
@ -193,6 +208,59 @@ RED.nodes = (function() {
|
|||||||
return (1+Math.random()*4294967295).toString(16);
|
return (1+Math.random()*4294967295).toString(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseNodePropertyTypeString(typeString) {
|
||||||
|
typeString = typeString.trim();
|
||||||
|
var c;
|
||||||
|
var pos = 0;
|
||||||
|
var isArray = /\[\]$/.test(typeString);
|
||||||
|
if (isArray) {
|
||||||
|
typeString = typeString.substring(0,typeString.length-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var l = typeString.length;
|
||||||
|
var inBrackets = false;
|
||||||
|
var inToken = false;
|
||||||
|
var currentToken = "";
|
||||||
|
var types = [];
|
||||||
|
while (pos < l) {
|
||||||
|
c = typeString[pos];
|
||||||
|
if (inToken) {
|
||||||
|
if (c === "|") {
|
||||||
|
types.push(currentToken.trim())
|
||||||
|
currentToken = "";
|
||||||
|
inToken = false;
|
||||||
|
} else if (c === ")") {
|
||||||
|
types.push(currentToken.trim())
|
||||||
|
currentToken = "";
|
||||||
|
inBrackets = false;
|
||||||
|
inToken = false;
|
||||||
|
} else {
|
||||||
|
currentToken += c;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (c === "(") {
|
||||||
|
if (inBrackets) {
|
||||||
|
throw new Error("Invalid character '"+c+"' at position "+pos)
|
||||||
|
}
|
||||||
|
inBrackets = true;
|
||||||
|
} else if (c !== " ") {
|
||||||
|
inToken = true;
|
||||||
|
currentToken = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
currentToken = currentToken.trim();
|
||||||
|
if (currentToken.length > 0) {
|
||||||
|
types.push(currentToken)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
types: types,
|
||||||
|
array: isArray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function addNode(n) {
|
function addNode(n) {
|
||||||
if (n.type.indexOf("subflow") !== 0) {
|
if (n.type.indexOf("subflow") !== 0) {
|
||||||
n["_"] = n._def._;
|
n["_"] = n._def._;
|
||||||
@ -788,16 +856,29 @@ RED.nodes = (function() {
|
|||||||
if (node.type !== "subflow") {
|
if (node.type !== "subflow") {
|
||||||
var convertedNode = RED.nodes.convertNode(node);
|
var convertedNode = RED.nodes.convertNode(node);
|
||||||
for (var d in node._def.defaults) {
|
for (var d in node._def.defaults) {
|
||||||
if (node._def.defaults[d].type && node[d] in configNodes) {
|
if (node._def.defaults[d].type) {
|
||||||
var confNode = configNodes[node[d]];
|
var nodeList = node[d];
|
||||||
var exportable = registry.getNodeType(node._def.defaults[d].type).exportable;
|
if (!Array.isArray(nodeList)) {
|
||||||
if ((exportable == null || exportable)) {
|
nodeList = [nodeList];
|
||||||
if (!(node[d] in exportedConfigNodes)) {
|
|
||||||
exportedConfigNodes[node[d]] = true;
|
|
||||||
set.push(confNode);
|
|
||||||
}
|
}
|
||||||
|
nodeList = nodeList.filter(function(id) {
|
||||||
|
if (id in configNodes) {
|
||||||
|
var confNode = configNodes[id];
|
||||||
|
if (confNode._def.exportable !== false) {
|
||||||
|
if (!(id in exportedConfigNodes)) {
|
||||||
|
exportedConfigNodes[id] = true;
|
||||||
|
set.push(confNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
if (nodeList.length === 0) {
|
||||||
|
convertedNode[d] = Array.isArray(node[d])?[]:""
|
||||||
} else {
|
} else {
|
||||||
convertedNode[d] = "";
|
convertedNode[d] = Array.isArray(node[d])?nodeList:nodeList[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1588,15 +1669,6 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: make this a part of the node definition so it doesn't have to
|
|
||||||
// be hardcoded here
|
|
||||||
var nodeTypeArrayReferences = {
|
|
||||||
"catch":"scope",
|
|
||||||
"status":"scope",
|
|
||||||
"complete": "scope",
|
|
||||||
"link in":"links",
|
|
||||||
"link out":"links"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remap all wires and config node references
|
// Remap all wires and config node references
|
||||||
for (i=0;i<new_nodes.length;i++) {
|
for (i=0;i<new_nodes.length;i++) {
|
||||||
@ -1625,19 +1697,24 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
for (var d3 in n._def.defaults) {
|
for (var d3 in n._def.defaults) {
|
||||||
if (n._def.defaults.hasOwnProperty(d3)) {
|
if (n._def.defaults.hasOwnProperty(d3)) {
|
||||||
if (n._def.defaults[d3].type && node_map[n[d3]]) {
|
if (n._def.defaults[d3].type) {
|
||||||
configNode = node_map[n[d3]];
|
var nodeList = n[d3];
|
||||||
n[d3] = configNode.id;
|
if (!Array.isArray(nodeList)) {
|
||||||
if (configNode.users.indexOf(n) === -1) {
|
nodeList = [nodeList];
|
||||||
configNode.users.push(n);
|
|
||||||
}
|
}
|
||||||
} else if (nodeTypeArrayReferences.hasOwnProperty(n.type) && nodeTypeArrayReferences[n.type] === d3 && n[d3] !== undefined && n[d3] !== null) {
|
nodeList = nodeList.map(function(id) {
|
||||||
for (var j = 0;j<n[d3].length;j++) {
|
var node = node_map[id];
|
||||||
if (node_map[n[d3][j]]) {
|
if (node) {
|
||||||
n[d3][j] = node_map[n[d3][j]].id;
|
if (node._def.category === 'config') {
|
||||||
|
if (node.users.indexOf(n) === -1) {
|
||||||
|
node.users.push(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return node.id;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
})
|
||||||
|
n[d3] = Array.isArray(n[d3])?nodeList:nodeList[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,6 +186,7 @@ var RED = (function() {
|
|||||||
RED.workspaces.show(currentHash.substring(6));
|
RED.workspaces.show(currentHash.substring(6));
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
console.warn(err);
|
||||||
RED.notify(
|
RED.notify(
|
||||||
RED._("event.importError", {message: err.message}),
|
RED._("event.importError", {message: err.message}),
|
||||||
{
|
{
|
||||||
|
@ -444,8 +444,9 @@ RED.editor = (function() {
|
|||||||
for (var d in definition.defaults) {
|
for (var d in definition.defaults) {
|
||||||
if (definition.defaults.hasOwnProperty(d)) {
|
if (definition.defaults.hasOwnProperty(d)) {
|
||||||
if (definition.defaults[d].type) {
|
if (definition.defaults[d].type) {
|
||||||
|
if (!definition.defaults[d]._type.array) {
|
||||||
var configTypeDef = RED.nodes.getType(definition.defaults[d].type);
|
var configTypeDef = RED.nodes.getType(definition.defaults[d].type);
|
||||||
if (configTypeDef) {
|
if (configTypeDef && configTypeDef.category === 'config') {
|
||||||
if (configTypeDef.exclusive) {
|
if (configTypeDef.exclusive) {
|
||||||
prepareConfigNodeButton(node,d,definition.defaults[d].type,prefix);
|
prepareConfigNodeButton(node,d,definition.defaults[d].type,prefix);
|
||||||
} else {
|
} else {
|
||||||
@ -455,6 +456,7 @@ RED.editor = (function() {
|
|||||||
console.log("Unknown type:", definition.defaults[d].type);
|
console.log("Unknown type:", definition.defaults[d].type);
|
||||||
preparePropertyEditor(node,d,prefix,definition.defaults);
|
preparePropertyEditor(node,d,prefix,definition.defaults);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
preparePropertyEditor(node,d,prefix,definition.defaults);
|
preparePropertyEditor(node,d,prefix,definition.defaults);
|
||||||
}
|
}
|
||||||
|
@ -338,7 +338,7 @@ RED.sidebar.info = (function() {
|
|||||||
count++;
|
count++;
|
||||||
propRow = $('<tr class="red-ui-help-info-property-row'+(expandedSections.property?"":" hide")+'"><td></td><td></td></tr>').appendTo(tableBody);
|
propRow = $('<tr class="red-ui-help-info-property-row'+(expandedSections.property?"":" hide")+'"><td></td><td></td></tr>').appendTo(tableBody);
|
||||||
$(propRow.children()[0]).text(n);
|
$(propRow.children()[0]).text(n);
|
||||||
if (defaults[n].type) {
|
if (defaults[n].type && !defaults[n]._type.array) {
|
||||||
var configNode = RED.nodes.node(val);
|
var configNode = RED.nodes.node(val);
|
||||||
if (!configNode) {
|
if (!configNode) {
|
||||||
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
|
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
|
||||||
|
@ -131,10 +131,10 @@
|
|||||||
width: 120px;
|
width: 120px;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
position: relative;
|
position: relative;
|
||||||
&:not(.red-ui-palette-node-config):first-child {
|
&:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):first-child {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
&:not(.red-ui-palette-node-config):last-child {
|
&:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):first-child {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
color:"#c0edc0",
|
color:"#c0edc0",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
scope: {value:[]},
|
scope: {value:[], type:"*[]"},
|
||||||
uncaught: {value:false}
|
uncaught: {value:false}
|
||||||
},
|
},
|
||||||
inputs:0,
|
inputs:0,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
color:"#e49191",
|
color:"#e49191",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
scope: {value:null},
|
scope: {value:null, type:"*[]"},
|
||||||
uncaught: {value:false}
|
uncaught: {value:false}
|
||||||
},
|
},
|
||||||
inputs:0,
|
inputs:0,
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
color:"#94c1d0",
|
color:"#94c1d0",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
scope: {value:null}
|
scope: {value:null, type:"*[]"}
|
||||||
},
|
},
|
||||||
inputs:0,
|
inputs:0,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
|
@ -187,7 +187,7 @@
|
|||||||
color:"#ddd",//"#87D8CF",
|
color:"#ddd",//"#87D8CF",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
links: { value: [] }
|
links: { value: [], type:"link out[]" }
|
||||||
},
|
},
|
||||||
inputs:0,
|
inputs:0,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
@ -216,7 +216,7 @@
|
|||||||
color:"#ddd",//"#87D8CF",
|
color:"#ddd",//"#87D8CF",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""},
|
name: {value:""},
|
||||||
links: { value: []}
|
links: { value: [], type:"link in[]"}
|
||||||
},
|
},
|
||||||
align:"right",
|
align:"right",
|
||||||
inputs:1,
|
inputs:1,
|
||||||
|
Loading…
Reference in New Issue
Block a user