mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
44 Commits
fix-link-t
...
4133-mqtt-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a790136164 | ||
|
|
32a49a1ef1 | ||
|
|
4b88775183 | ||
|
|
29db82625f | ||
|
|
2b6c9e3439 | ||
|
|
9ea4853c89 | ||
|
|
3b5e21761b | ||
|
|
2d76bf29cf | ||
|
|
c21f7abe4e | ||
|
|
8c191263c0 | ||
|
|
2679ff277c | ||
|
|
9e3f148273 | ||
|
|
7e9042e9f7 | ||
|
|
67c5a248ad | ||
|
|
e8ddee24a9 | ||
|
|
be4eab65f6 | ||
|
|
c0650cc0f5 | ||
|
|
02c7d014cb | ||
|
|
67dd7e30fa | ||
|
|
e9a08af73b | ||
|
|
08b1ef2766 | ||
|
|
667d8673d4 | ||
|
|
d44ea9d558 | ||
|
|
86dfe86813 | ||
|
|
246409970d | ||
|
|
841f1849c8 | ||
|
|
00e7e4d43c | ||
|
|
ee43a845aa | ||
|
|
a7cc66af93 | ||
|
|
f8701cfed0 | ||
|
|
6b205bf303 | ||
|
|
6fbcec8b98 | ||
|
|
c30e57c31d | ||
|
|
df3dc36874 | ||
|
|
7b71d8d212 | ||
|
|
2eaae4b83f | ||
|
|
3c66af9506 | ||
|
|
e5d579c1bb | ||
|
|
ee811ca89b | ||
|
|
8e4933041d | ||
|
|
1f3559e14f | ||
|
|
f1fa1bbe4e | ||
|
|
5eb46c570d | ||
|
|
e30df544db |
10
.github/workflows/tests.yml
vendored
10
.github/workflows/tests.yml
vendored
@@ -29,8 +29,8 @@ jobs:
|
||||
- name: Run tests
|
||||
run: |
|
||||
npm run test
|
||||
- name: Publish to coveralls.io
|
||||
if: ${{ matrix.node-version == 14 }}
|
||||
uses: coverallsapp/github-action@v1.1.2
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
# - name: Publish to coveralls.io
|
||||
# if: ${{ matrix.node-version == 14 }}
|
||||
# uses: coverallsapp/github-action@v1.1.2
|
||||
# with:
|
||||
# github-token: ${{ github.token }}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
http://nodered.org
|
||||
|
||||
[](https://travis-ci.org/node-red/node-red)
|
||||
[](https://coveralls.io/r/node-red/node-red?branch=master)
|
||||
[](https://github.com/node-red/node-red/actions?query=branch%3Amaster)
|
||||
|
||||
Low-code programming for event-driven applications.
|
||||
|
||||
|
||||
@@ -491,6 +491,7 @@
|
||||
"unassigned": "Unassigned",
|
||||
"global": "global",
|
||||
"workspace": "workspace",
|
||||
"editor": "edit dialog",
|
||||
"selectAll": "Select all",
|
||||
"selectNone": "Select none",
|
||||
"selectAllConnected": "Select connected",
|
||||
|
||||
@@ -491,6 +491,7 @@
|
||||
"unassigned": "未割当",
|
||||
"global": "グローバル",
|
||||
"workspace": "ワークスペース",
|
||||
"editor": "編集ダイアログ",
|
||||
"selectAll": "全てのノードを選択",
|
||||
"selectNone": "選択を外す",
|
||||
"selectAllConnected": "接続されたノードを選択",
|
||||
|
||||
@@ -2095,16 +2095,27 @@ RED.nodes = (function() {
|
||||
} else if (n.type.substring(0,7) === "subflow") {
|
||||
var parentId = n.type.split(":")[1];
|
||||
var subflow = subflow_denylist[parentId]||subflow_map[parentId]||getSubflow(parentId);
|
||||
if (createNewIds || options.importMap[n.id] === "copy") {
|
||||
parentId = subflow.id;
|
||||
node.type = "subflow:"+parentId;
|
||||
node._def = registry.getNodeType(node.type);
|
||||
delete node.i;
|
||||
if (!subflow){
|
||||
node._def = {
|
||||
color:"#fee",
|
||||
defaults: {},
|
||||
label: "unknown: "+n.type,
|
||||
labelStyle: "red-ui-flow-node-label-italic",
|
||||
outputs: n.outputs|| (n.wires && n.wires.length) || 0,
|
||||
set: registry.getNodeSet("node-red/unknown")
|
||||
}
|
||||
} else {
|
||||
if (createNewIds || options.importMap[n.id] === "copy") {
|
||||
parentId = subflow.id;
|
||||
node.type = "subflow:"+parentId;
|
||||
node._def = registry.getNodeType(node.type);
|
||||
delete node.i;
|
||||
}
|
||||
node.name = n.name;
|
||||
node.outputs = subflow.out.length;
|
||||
node.inputs = subflow.in.length;
|
||||
node.env = n.env;
|
||||
}
|
||||
node.name = n.name;
|
||||
node.outputs = subflow.out.length;
|
||||
node.inputs = subflow.in.length;
|
||||
node.env = n.env;
|
||||
} else if (n.type === 'junction') {
|
||||
node._def = {defaults:{}}
|
||||
node._config.x = node.x
|
||||
|
||||
@@ -47,7 +47,7 @@ RED.actionList = (function() {
|
||||
var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog);
|
||||
searchInput = $('<input type="text" data-i18n="[placeholder]keyboard.filterActions">').appendTo(searchDiv).searchBox({
|
||||
change: function() {
|
||||
filterTerm = $(this).val().trim();
|
||||
filterTerm = $(this).val().trim().toLowerCase();
|
||||
filterTerms = filterTerm.split(" ");
|
||||
searchResults.editableList('filter');
|
||||
searchResults.find("li.selected").removeClass("selected");
|
||||
|
||||
@@ -37,13 +37,13 @@ RED.clipboard = (function() {
|
||||
// IE11 workaround
|
||||
// IE does not support data uri scheme for downloading data
|
||||
var blob = new Blob([data], {
|
||||
type: "data:text/plain;charset=utf-8"
|
||||
type: "data:application/json;charset=utf-8"
|
||||
});
|
||||
navigator.msSaveBlob(blob, file);
|
||||
}
|
||||
else {
|
||||
var element = document.createElement('a');
|
||||
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data));
|
||||
element.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(data));
|
||||
element.setAttribute('download', file);
|
||||
element.style.display = 'none';
|
||||
document.body.appendChild(element);
|
||||
|
||||
@@ -45,11 +45,13 @@ RED.editor = (function() {
|
||||
var hasChanged;
|
||||
if (node.type.indexOf("subflow:")===0) {
|
||||
subflow = RED.nodes.subflow(node.type.substring(8));
|
||||
isValid = subflow.valid;
|
||||
hasChanged = subflow.changed;
|
||||
if (isValid === undefined) {
|
||||
isValid = validateNode(subflow);
|
||||
if (subflow){
|
||||
isValid = subflow.valid;
|
||||
hasChanged = subflow.changed;
|
||||
if (isValid === undefined) {
|
||||
isValid = validateNode(subflow);
|
||||
hasChanged = subflow.changed;
|
||||
}
|
||||
}
|
||||
validationErrors = validateNodeProperties(node, node._def.defaults, node);
|
||||
node.valid = isValid && validationErrors.length === 0;
|
||||
|
||||
@@ -491,7 +491,11 @@ RED.keyboard = (function() {
|
||||
okButton.attr("disabled",!valid);
|
||||
});
|
||||
|
||||
var scopeSelect = $('<select><option value="*" data-i18n="keyboard.global"></option><option value="red-ui-workspace" data-i18n="keyboard.workspace"></option></select>').appendTo(scope);
|
||||
var scopeSelect = $('<select>'+
|
||||
'<option value="*" data-i18n="keyboard.global"></option>'+
|
||||
'<option value="red-ui-workspace" data-i18n="keyboard.workspace"></option>'+
|
||||
'<option value="red-ui-editor-stack" data-i18n="keyboard.editor"></option>'+
|
||||
'</select>').appendTo(scope);
|
||||
scopeSelect.i18n();
|
||||
if (object.scope === "workspace") {
|
||||
object.scope = "red-ui-workspace";
|
||||
|
||||
@@ -747,14 +747,14 @@ RED.projects = (function() {
|
||||
var row = $('<div class="form-row"></div>').appendTo(body);
|
||||
$('<label for="red-ui-projects-dialog-screen-create-project-file">'+RED._("projects.default-files.flow-file")+'</label>').appendTo(row);
|
||||
var subrow = $('<div style="position:relative;"></div>').appendTo(row);
|
||||
var defaultFlowFile = (createProjectOptions.files &&createProjectOptions.files.flow) || (RED.settings.files && RED.settings.files.flow)||"flow.json";
|
||||
var defaultFlowFile = (createProjectOptions.files &&createProjectOptions.files.flow) || (RED.settings.files && RED.settings.files.flow) || "flows.json";
|
||||
projectFlowFileInput = $('<input id="red-ui-projects-dialog-screen-create-project-file" type="text">').val(defaultFlowFile)
|
||||
.on("change keyup paste",validateForm)
|
||||
.appendTo(subrow);
|
||||
$('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow);
|
||||
$('<label class="red-ui-projects-edit-form-sublabel"><small>*.json</small></label>').appendTo(row);
|
||||
|
||||
var defaultCredentialsFile = (createProjectOptions.files &&createProjectOptions.files.credentials) || (RED.settings.files && RED.settings.files.credentials)||"flow_cred.json";
|
||||
var defaultCredentialsFile = (createProjectOptions.files &&createProjectOptions.files.credentials) || (RED.settings.files && RED.settings.files.credentials) || "flows_cred.json";
|
||||
row = $('<div class="form-row"></div>').appendTo(body);
|
||||
$('<label for="red-ui-projects-dialog-screen-create-project-credfile">'+RED._("projects.default-files.credentials-file")+'</label>').appendTo(row);
|
||||
subrow = $('<div style="position:relative;"></div>').appendTo(row);
|
||||
@@ -1257,7 +1257,7 @@ RED.projects = (function() {
|
||||
row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty"></div>').appendTo(container);
|
||||
$('<label for="red-ui-projects-dialog-screen-create-project-file">'+RED._("projects.create.flow-file")+'</label>').appendTo(row);
|
||||
subrow = $('<div style="position:relative;"></div>').appendTo(row);
|
||||
projectFlowFileInput = $('<input id="red-ui-projects-dialog-screen-create-project-file" type="text">').val("flow.json")
|
||||
projectFlowFileInput = $('<input id="red-ui-projects-dialog-screen-create-project-file" type="text">').val("flows.json")
|
||||
.on("change keyup paste",validateForm)
|
||||
.appendTo(subrow);
|
||||
$('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow);
|
||||
|
||||
@@ -663,24 +663,23 @@ RED.subflow = (function() {
|
||||
var candidateOutputs = [];
|
||||
var candidateInputNodes = {};
|
||||
|
||||
var boundingBox = [nodeList[0].x,
|
||||
nodeList[0].y,
|
||||
nodeList[0].x,
|
||||
nodeList[0].y];
|
||||
var boundingBox = [nodeList[0].x-(nodeList[0].w/2),
|
||||
nodeList[0].y-(nodeList[0].h/2),
|
||||
nodeList[0].x+(nodeList[0].w/2),
|
||||
nodeList[0].y+(nodeList[0].h/2)];
|
||||
|
||||
for (i=0;i<nodeList.length;i++) {
|
||||
n = nodeList[i];
|
||||
nodes[n.id] = {n:n,outputs:{}};
|
||||
boundingBox = [
|
||||
Math.min(boundingBox[0],n.x),
|
||||
Math.min(boundingBox[1],n.y),
|
||||
Math.max(boundingBox[2],n.x),
|
||||
Math.max(boundingBox[3],n.y)
|
||||
Math.min(boundingBox[0],n.x-(n.w/2)),
|
||||
Math.min(boundingBox[1],n.y-(n.h/2)),
|
||||
Math.max(boundingBox[2],n.x+(n.w/2)),
|
||||
Math.max(boundingBox[3],n.y+(n.h/2))
|
||||
]
|
||||
}
|
||||
var offsetX = snapToGrid(boundingBox[0] - 200);
|
||||
var offsetY = snapToGrid(boundingBox[1] - 80);
|
||||
|
||||
var offsetX = snapToGrid(boundingBox[0] - 140);
|
||||
var offsetY = snapToGrid(boundingBox[1] - 60);
|
||||
|
||||
var center = [
|
||||
snapToGrid((boundingBox[2]+boundingBox[0]) / 2),
|
||||
|
||||
@@ -2646,6 +2646,16 @@ RED.view = (function() {
|
||||
var result = RED.nodes.removeJunction(node)
|
||||
removedJunctions.push(node);
|
||||
removedLinks = removedLinks.concat(result.links);
|
||||
if (node.g) {
|
||||
var group = RED.nodes.group(node.g);
|
||||
if (selectedGroups.indexOf(group) === -1) {
|
||||
// Don't use RED.group.removeFromGroup as that emits
|
||||
// a change event on the node - but we're deleting it
|
||||
var index = group.nodes.indexOf(node);
|
||||
group.nodes.splice(index,1);
|
||||
RED.group.markDirty(group);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (node.direction === "out") {
|
||||
removedSubflowOutputs.push(node);
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding:0;
|
||||
|
||||
overflow-wrap: anywhere;
|
||||
li {
|
||||
display: inline-block;
|
||||
padding:0;
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
.red-ui-palette-search {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: var(--red-ui-secondary-background);
|
||||
background: var(--red-ui-form-input-background);
|
||||
text-align: center;
|
||||
height: 35px;
|
||||
padding: 3px;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
padding: 8px;
|
||||
border-radius: 2px;
|
||||
background: var(--red-ui-popover-background);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.red-ui-popover:after, .red-ui-popover:before {
|
||||
border: solid transparent;
|
||||
|
||||
@@ -108,6 +108,8 @@
|
||||
}
|
||||
.red-ui-search-result-node-label {
|
||||
color: var(--red-ui-secondary-text-color);
|
||||
width: 240px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
> span {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
border-bottom: 1px solid var(--red-ui-secondary-border-color);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,11 @@ module.exports = function(RED) {
|
||||
}
|
||||
else { node.previous = {}; }
|
||||
}
|
||||
var value = RED.util.getMessageProperty(msg,node.property);
|
||||
var value;
|
||||
try {
|
||||
value = RED.util.getMessageProperty(msg,node.property);
|
||||
}
|
||||
catch(e) { }
|
||||
if (value !== undefined) {
|
||||
var t = "_no_topic";
|
||||
if (node.septopics) { t = topic || t; }
|
||||
|
||||
@@ -697,7 +697,8 @@ module.exports = function(RED) {
|
||||
node.options.rejectUnauthorized = (node.verifyservercert == "true" || node.verifyservercert === true);
|
||||
}
|
||||
}
|
||||
|
||||
node.v5 = () => node.options && node.options.protocolVersion == 5
|
||||
node.subscriptionIdentifiersAvailable = () => node.v5() && node.serverProperties && node.serverProperties.subscriptionIdentifiersAvailable
|
||||
n.autoConnect = n.autoConnect === "false" || n.autoConnect === false ? false : true;
|
||||
node.setOptions(n, true);
|
||||
|
||||
@@ -920,7 +921,12 @@ module.exports = function(RED) {
|
||||
};
|
||||
node.subscriptions[topic][ref] = sub;
|
||||
if (node.connected) {
|
||||
const subIdsAvailable = node.subscriptionIdentifiersAvailable()
|
||||
node._clientOn('message',sub.handler);
|
||||
// if the broker doesn't support subscription identifiers (e.g. AWS core), then don't send them
|
||||
if (options.properties && options.properties.subscriptionIdentifier && subIdsAvailable !== true) {
|
||||
delete options.properties.subscriptionIdentifier
|
||||
}
|
||||
node.client.subscribe(topic, options);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -199,7 +199,9 @@ function parseConfig(config) {
|
||||
if (subflowDetails) {
|
||||
var subflowType = subflowDetails[1]
|
||||
n.subflow = subflowType;
|
||||
flow.subflows[subflowType].instances.push(n)
|
||||
if (flow.subflows[subflowType]) {
|
||||
flow.subflows[subflowType].instances.push(n)
|
||||
}
|
||||
}
|
||||
if (container) {
|
||||
container.nodes[n.id] = n;
|
||||
|
||||
@@ -854,7 +854,7 @@ describe('inject node', function() {
|
||||
});
|
||||
n1.on("call:error", function(err) {
|
||||
count++;
|
||||
if (count == 2) {
|
||||
if (count == 1) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user