mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
33 Commits
2.2.2
...
fontawesom
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd2462135b | ||
|
|
3649f10600 | ||
|
|
a0acc89fcb | ||
|
|
64d1a82920 | ||
|
|
2396e28479 | ||
|
|
db1ad0df63 | ||
|
|
3c0b74005b | ||
|
|
93ff667df1 | ||
|
|
99d824a999 | ||
|
|
97d2b5df15 | ||
|
|
6a5c50ff77 | ||
|
|
c948573c2d | ||
|
|
5233bc501c | ||
|
|
ad96c6f838 | ||
|
|
0e92f68b4a | ||
|
|
08295eb807 | ||
|
|
fce4f0c116 | ||
|
|
94e8fce40a | ||
|
|
c75bebfc90 | ||
|
|
3e102ef760 | ||
|
|
c07eddbd97 | ||
|
|
0533c08438 | ||
|
|
fba95e6a42 | ||
|
|
95d3a8cc22 | ||
|
|
63ebadc526 | ||
|
|
fe47b07229 | ||
|
|
62315fd478 | ||
|
|
c6104195f6 | ||
|
|
56b85e4194 | ||
|
|
6431c43d0e | ||
|
|
a62107fbd1 | ||
|
|
2f66915a9f | ||
|
|
a508177e21 |
@@ -634,14 +634,7 @@
|
||||
"empty": "leer",
|
||||
"globalConfig": "Globale Konfigurations-Nodes",
|
||||
"triggerAction": "Auslösen",
|
||||
"find": "Suche im Arbeitsbereich",
|
||||
"search": {
|
||||
"configNodes": "Konfigurations-Nodes",
|
||||
"unusedConfigNodes": "Unbenutzte Konfigurations-Nodes",
|
||||
"invalidNodes": "Ungültige Nodes",
|
||||
"uknownNodes": "Unbekannte Nodes",
|
||||
"unusedSubflows": "Unbenutzte Subflows"
|
||||
}
|
||||
"find": "Suche im Arbeitsbereich"
|
||||
},
|
||||
"help": {
|
||||
"name": "Hilfe",
|
||||
@@ -863,7 +856,14 @@
|
||||
},
|
||||
"search": {
|
||||
"empty": "Keine Übereinstimmungen gefunden",
|
||||
"addNode": "Node hinzufügen ..."
|
||||
"addNode": "Node hinzufügen ...",
|
||||
"options": {
|
||||
"configNodes": "Konfigurations-Nodes",
|
||||
"unusedConfigNodes": "Unbenutzte Konfigurations-Nodes",
|
||||
"invalidNodes": "Ungültige Nodes",
|
||||
"uknownNodes": "Unbekannte Nodes",
|
||||
"unusedSubflows": "Unbenutzte Subflows"
|
||||
}
|
||||
},
|
||||
"expressionEditor": {
|
||||
"functions": "Funktionen",
|
||||
|
||||
@@ -149,7 +149,11 @@
|
||||
"toggle-navigator": "Toggle navigator",
|
||||
"zoom-out": "Zoom out",
|
||||
"zoom-reset": "Reset zoom",
|
||||
"zoom-in": "Zoom in"
|
||||
"zoom-in": "Zoom in",
|
||||
"search-flows": "Search flows",
|
||||
"search-prev": "Previous",
|
||||
"search-next": "Next",
|
||||
"search-counter": "\"__term__\" __result__ of __count__"
|
||||
},
|
||||
"user": {
|
||||
"loggedInAs": "Logged in as __name__",
|
||||
@@ -497,7 +501,8 @@
|
||||
"redoChange": "Redo",
|
||||
"searchBox": "Open search box",
|
||||
"managePalette": "Manage palette",
|
||||
"actionList":"Action list"
|
||||
"actionList": "Action list",
|
||||
"splitWiresWithLinks": "Split selection with Link nodes"
|
||||
},
|
||||
"library": {
|
||||
"library": "Library",
|
||||
@@ -667,15 +672,7 @@
|
||||
"empty": "empty",
|
||||
"globalConfig": "Global Configuration Nodes",
|
||||
"triggerAction": "Trigger action",
|
||||
"find": "Find in workspace",
|
||||
"search": {
|
||||
"configNodes": "Configuration nodes",
|
||||
"unusedConfigNodes": "Unused configuration nodes",
|
||||
"invalidNodes": "Invalid nodes",
|
||||
"uknownNodes": "Unknown nodes",
|
||||
"unusedSubflows": "Unused subflows",
|
||||
"hiddenFlows": "Hidden flows"
|
||||
}
|
||||
"find": "Find in workspace"
|
||||
},
|
||||
"help": {
|
||||
"name": "Help",
|
||||
@@ -899,7 +896,16 @@
|
||||
"history": "Search history",
|
||||
"clear": "clear all",
|
||||
"empty": "No matches found",
|
||||
"addNode": "add a node..."
|
||||
"addNode": "add a node...",
|
||||
"options": {
|
||||
"configNodes": "Configuration nodes",
|
||||
"unusedConfigNodes": "Unused configuration nodes",
|
||||
"invalidNodes": "Invalid nodes",
|
||||
"uknownNodes": "Unknown nodes",
|
||||
"unusedSubflows": "Unused subflows",
|
||||
"hiddenFlows": "Hidden flows",
|
||||
"modifiedNodes": "Modified nodes and flows"
|
||||
}
|
||||
},
|
||||
"expressionEditor": {
|
||||
"functions": "Functions",
|
||||
|
||||
@@ -667,15 +667,7 @@
|
||||
"empty": "空",
|
||||
"globalConfig": "グローバル設定ノード",
|
||||
"triggerAction": "アクションを実行",
|
||||
"find": "ワークスペース内を検索",
|
||||
"search": {
|
||||
"configNodes": "設定ノード",
|
||||
"unusedConfigNodes": "未使用の設定ノード",
|
||||
"invalidNodes": "不正なノード",
|
||||
"uknownNodes": "未知のノード",
|
||||
"unusedSubflows": "未使用のサブフロー",
|
||||
"hiddenFlows": "非表示のフロー"
|
||||
}
|
||||
"find": "ワークスペース内を検索"
|
||||
},
|
||||
"help": {
|
||||
"name": "ヘルプ",
|
||||
@@ -899,7 +891,15 @@
|
||||
"history": "検索履歴",
|
||||
"clear": "全て削除",
|
||||
"empty": "一致したものが見つかりませんでした",
|
||||
"addNode": "ノードを追加..."
|
||||
"addNode": "ノードを追加...",
|
||||
"options": {
|
||||
"configNodes": "設定ノード",
|
||||
"unusedConfigNodes": "未使用の設定ノード",
|
||||
"invalidNodes": "不正なノード",
|
||||
"uknownNodes": "未知のノード",
|
||||
"unusedSubflows": "未使用のサブフロー",
|
||||
"hiddenFlows": "非表示のフロー"
|
||||
}
|
||||
},
|
||||
"expressionEditor": {
|
||||
"functions": "関数",
|
||||
|
||||
@@ -650,14 +650,7 @@
|
||||
"empty": "пусто",
|
||||
"globalConfig": "Глобальные конфиг узлы",
|
||||
"triggerAction": "Вызвать действие",
|
||||
"find": "Найти в рабочей области",
|
||||
"search": {
|
||||
"configNodes": "Узлы конфигурации",
|
||||
"unusedConfigNodes": "Неиспользуемые узлы конфигурации",
|
||||
"invalidNodes": "Недействительные узлы",
|
||||
"uknownNodes": "Неизвестные узлы",
|
||||
"unusedSubflows": "Неиспользуемые подпотоки"
|
||||
}
|
||||
"find": "Найти в рабочей области"
|
||||
},
|
||||
"help": {
|
||||
"name": "Справка",
|
||||
@@ -888,7 +881,14 @@
|
||||
},
|
||||
"search": {
|
||||
"empty": "Ничего не найдено",
|
||||
"addNode": "добавить узел..."
|
||||
"addNode": "добавить узел...",
|
||||
"options": {
|
||||
"configNodes": "Узлы конфигурации",
|
||||
"unusedConfigNodes": "Неиспользуемые узлы конфигурации",
|
||||
"invalidNodes": "Недействительные узлы",
|
||||
"uknownNodes": "Неизвестные узлы",
|
||||
"unusedSubflows": "Неиспользуемые подпотоки"
|
||||
}
|
||||
},
|
||||
"expressionEditor": {
|
||||
"functions": "Функции",
|
||||
|
||||
@@ -614,14 +614,7 @@
|
||||
"empty": "空的",
|
||||
"globalConfig": "全局配置节点",
|
||||
"triggerAction": "触发动作",
|
||||
"find": "在工作区中查找",
|
||||
"search": {
|
||||
"configNodes": "配置节点",
|
||||
"unusedConfigNodes": "未使用的配置节点",
|
||||
"invalidNodes": "无效的节点",
|
||||
"uknownNodes": "未知的节点",
|
||||
"unusedSubflows": "未使用的子流程"
|
||||
}
|
||||
"find": "在工作区中查找"
|
||||
},
|
||||
"help": {
|
||||
"name": "帮助",
|
||||
@@ -842,7 +835,14 @@
|
||||
},
|
||||
"search": {
|
||||
"empty": "找不到匹配",
|
||||
"addNode": "添加一个节点..."
|
||||
"addNode": "添加一个节点...",
|
||||
"options": {
|
||||
"configNodes": "配置节点",
|
||||
"unusedConfigNodes": "未使用的配置节点",
|
||||
"invalidNodes": "无效的节点",
|
||||
"uknownNodes": "未知的节点",
|
||||
"unusedSubflows": "未使用的子流程"
|
||||
}
|
||||
},
|
||||
"expressionEditor": {
|
||||
"functions": "功能",
|
||||
|
||||
@@ -614,14 +614,7 @@
|
||||
"empty": "空的",
|
||||
"globalConfig": "全局配置節點",
|
||||
"triggerAction": "觸發動作",
|
||||
"find": "在工作區中查找",
|
||||
"search": {
|
||||
"configNodes": "配置節點",
|
||||
"unusedConfigNodes": "未使用的配置節點",
|
||||
"invalidNodes": "無效的節點",
|
||||
"uknownNodes": "未知的節點",
|
||||
"unusedSubflows": "未使用的子流程"
|
||||
}
|
||||
"find": "在工作區中查找"
|
||||
},
|
||||
"help": {
|
||||
"name": "幫助",
|
||||
@@ -842,7 +835,14 @@
|
||||
},
|
||||
"search": {
|
||||
"empty": "找不到匹配",
|
||||
"addNode": "添加一個節點..."
|
||||
"addNode": "添加一個節點...",
|
||||
"options": {
|
||||
"configNodes": "配置節點",
|
||||
"unusedConfigNodes": "未使用的配置節點",
|
||||
"invalidNodes": "無效的節點",
|
||||
"uknownNodes": "未知的節點",
|
||||
"unusedSubflows": "未使用的子流程"
|
||||
}
|
||||
},
|
||||
"expressionEditor": {
|
||||
"functions": "功能",
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
/**
|
||||
* An API for undo / redo history buffer
|
||||
* @namespace RED.history
|
||||
*/
|
||||
RED.history = (function() {
|
||||
var undoHistory = [];
|
||||
var redoHistory = [];
|
||||
@@ -101,6 +106,23 @@ RED.history = (function() {
|
||||
RED.nodes.removeLink(ev.links[i]);
|
||||
}
|
||||
}
|
||||
if (ev.junctions) {
|
||||
inverseEv.junctions = [];
|
||||
for (i=0;i<ev.junctions.length;i++) {
|
||||
inverseEv.junctions.push(ev.junctions[i]);
|
||||
RED.nodes.removeJunction(ev.junctions[i]);
|
||||
if (ev.junctions[i].g) {
|
||||
var group = RED.nodes.group(ev.junctions[i].g);
|
||||
var index = group.nodes.indexOf(ev.junctions[i]);
|
||||
if (index !== -1) {
|
||||
group.nodes.splice(index,1);
|
||||
RED.group.markDirty(group);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if (ev.groups) {
|
||||
inverseEv.groups = [];
|
||||
for (i = ev.groups.length - 1;i>=0;i--) {
|
||||
@@ -267,6 +289,21 @@ RED.history = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ev.junctions) {
|
||||
inverseEv.junctions = [];
|
||||
for (i=0;i<ev.junctions.length;i++) {
|
||||
inverseEv.junctions.push(ev.junctions[i]);
|
||||
RED.nodes.addJunction(ev.junctions[i]);
|
||||
if (ev.junctions[i].g) {
|
||||
group = RED.nodes.group(ev.junctions[i].g);
|
||||
if (group.nodes.indexOf(ev.junctions[i]) === -1) {
|
||||
group.nodes.push(ev.junctions[i]);
|
||||
}
|
||||
RED.group.markDirty(group)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (ev.links) {
|
||||
inverseEv.links = [];
|
||||
for (i=0;i<ev.links.length;i++) {
|
||||
|
||||
@@ -90,6 +90,10 @@
|
||||
"alt-a m": "core:align-selection-to-middle",
|
||||
"alt-a c": "core:align-selection-to-center",
|
||||
"alt-a h": "core:distribute-selection-horizontally",
|
||||
"alt-a v": "core:distribute-selection-vertically"
|
||||
"alt-a v": "core:distribute-selection-vertically",
|
||||
"shift-f": "core:search-previous",
|
||||
"f": "core:search-next",
|
||||
"alt-l l": "core:split-wire-with-link-nodes"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
/**
|
||||
* An Interface to nodes and utility functions for creating/adding/deleting nodes and links
|
||||
* @namespace RED.nodes
|
||||
*/
|
||||
RED.nodes = (function() {
|
||||
|
||||
var PORT_TYPE_INPUT = 1;
|
||||
@@ -33,6 +38,9 @@ RED.nodes = (function() {
|
||||
var groups = {};
|
||||
var groupsByZ = {};
|
||||
|
||||
var junctions = {};
|
||||
var junctionsByZ = {};
|
||||
|
||||
var initialLoad;
|
||||
|
||||
var dirty = false;
|
||||
@@ -814,6 +822,7 @@ RED.nodes = (function() {
|
||||
var removedNodes = [];
|
||||
var removedLinks = [];
|
||||
var removedGroups = [];
|
||||
var removedJunctions = [];
|
||||
if (ws) {
|
||||
delete workspaces[id];
|
||||
delete linkTabMap[id];
|
||||
@@ -822,7 +831,14 @@ RED.nodes = (function() {
|
||||
var node;
|
||||
|
||||
if (allNodes.hasTab(id)) {
|
||||
removedNodes = allNodes.getNodes(id).slice()
|
||||
removedNodes = allNodes.getNodes(id).filter(n => {
|
||||
if (n.type === 'junction') {
|
||||
removedJunctions.push(n)
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
for (i in configNodes) {
|
||||
if (configNodes.hasOwnProperty(i)) {
|
||||
@@ -837,6 +853,10 @@ RED.nodes = (function() {
|
||||
var result = removeNode(removedNodes[i].id);
|
||||
removedLinks = removedLinks.concat(result.links);
|
||||
}
|
||||
for (i=0;i<removedJunctions.length;i++) {
|
||||
var result = removeJunction(removedJunctions[i])
|
||||
removedLinks = removedLinks.concat(result.links)
|
||||
}
|
||||
|
||||
// Must get 'removedGroups' in the right order.
|
||||
// - start with the top-most groups
|
||||
@@ -856,7 +876,7 @@ RED.nodes = (function() {
|
||||
allNodes.removeTab(id);
|
||||
RED.events.emit('flows:remove',ws);
|
||||
}
|
||||
return {nodes:removedNodes,links:removedLinks, groups: removedGroups};
|
||||
return {nodes:removedNodes,links:removedLinks, groups: removedGroups, junctions: removedJunctions};
|
||||
}
|
||||
|
||||
function addSubflow(sf, createNewIds) {
|
||||
@@ -1113,7 +1133,7 @@ RED.nodes = (function() {
|
||||
delete node.env;
|
||||
}
|
||||
}
|
||||
if (n._def.category != "config") {
|
||||
if (n._def.category != "config" || n.type === 'junction') {
|
||||
node.x = n.x;
|
||||
node.y = n.y;
|
||||
if (exportDimensions) {
|
||||
@@ -1376,6 +1396,11 @@ RED.nodes = (function() {
|
||||
nns.push(convertNode(groups[i], opts));
|
||||
}
|
||||
}
|
||||
for (i in junctions) {
|
||||
if (junctions.hasOwnProperty(i)) {
|
||||
nns.push(convertNode(junctions[i], opts));
|
||||
}
|
||||
}
|
||||
for (i in configNodes) {
|
||||
if (configNodes.hasOwnProperty(i)) {
|
||||
nns.push(convertNode(configNodes[i], opts));
|
||||
@@ -1457,6 +1482,7 @@ RED.nodes = (function() {
|
||||
tabs: {},
|
||||
subflows: {},
|
||||
groups: {},
|
||||
junctions: {},
|
||||
configs: {},
|
||||
nodes: {},
|
||||
all: [],
|
||||
@@ -1472,6 +1498,8 @@ RED.nodes = (function() {
|
||||
imported.subflows[n.id] = n;
|
||||
} else if (n.type === "group") {
|
||||
imported.groups[n.id] = n;
|
||||
} else if (n.type === "junction") {
|
||||
imported.junctions[n.id] = n;
|
||||
} else if (n.hasOwnProperty("x") && n.hasOwnProperty("y")) {
|
||||
imported.nodes[n.id] = n;
|
||||
} else {
|
||||
@@ -1480,7 +1508,7 @@ RED.nodes = (function() {
|
||||
var nodeZ = n.z || "__global__";
|
||||
imported.zMap[nodeZ] = imported.zMap[nodeZ] || [];
|
||||
imported.zMap[nodeZ].push(n)
|
||||
if (allNodes.hasNode(n.id) || configNodes[n.id] || workspaces[n.id] || subflows[n.id] || groups[n.id]) {
|
||||
if (allNodes.hasNode(n.id) || configNodes[n.id] || workspaces[n.id] || subflows[n.id] || groups[n.id] || junctions[n.id]) {
|
||||
imported.conflicted[n.id] = n;
|
||||
}
|
||||
})
|
||||
@@ -1646,7 +1674,7 @@ RED.nodes = (function() {
|
||||
if (!options.generateIds) {
|
||||
if (!options.importMap[id]) {
|
||||
// No conflict resolution for this node
|
||||
var existing = allNodes.getNode(id) || configNodes[id] || workspaces[id] || subflows[id] || groups[id];
|
||||
var existing = allNodes.getNode(id) || configNodes[id] || workspaces[id] || subflows[id] || groups[id] || junctions[id];
|
||||
if (existing) {
|
||||
existingNodes.push({existing:existing, imported:n});
|
||||
}
|
||||
@@ -1700,6 +1728,7 @@ RED.nodes = (function() {
|
||||
n.type != "tab" &&
|
||||
n.type != "subflow" &&
|
||||
n.type != "group" &&
|
||||
n.type != 'junction' &&
|
||||
!registry.getNodeType(n.type) &&
|
||||
n.type.substring(0,8) != "subflow:" &&
|
||||
unknownTypes.indexOf(n.type)==-1) {
|
||||
@@ -1772,6 +1801,7 @@ RED.nodes = (function() {
|
||||
var new_nodes = [];
|
||||
var new_links = [];
|
||||
var new_groups = [];
|
||||
var new_junctions = [];
|
||||
var new_group_set = new Set();
|
||||
var nid;
|
||||
var def;
|
||||
@@ -1963,12 +1993,15 @@ RED.nodes = (function() {
|
||||
changed:false,
|
||||
_config:{}
|
||||
}
|
||||
if (n.type !== "group") {
|
||||
if (n.type !== "group" && n.type !== 'junction') {
|
||||
node.wires = n.wires||[];
|
||||
node.inputLabels = n.inputLabels;
|
||||
node.outputLabels = n.outputLabels;
|
||||
node.icon = n.icon;
|
||||
}
|
||||
if (n.type === 'junction') {
|
||||
node.wires = n.wires||[];
|
||||
}
|
||||
if (n.hasOwnProperty('l')) {
|
||||
node.l = n.l;
|
||||
}
|
||||
@@ -2037,6 +2070,15 @@ RED.nodes = (function() {
|
||||
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
|
||||
node._config.y = node.y
|
||||
node.inputs = 1
|
||||
node.outputs = 1
|
||||
node.w = 0;
|
||||
node.h = 0;
|
||||
|
||||
} else {
|
||||
if (!node._def) {
|
||||
if (node.x && node.y) {
|
||||
@@ -2120,7 +2162,9 @@ RED.nodes = (function() {
|
||||
node_map[n.id] = node;
|
||||
// If an 'unknown' config node, it will not have been caught by the
|
||||
// proper config node handling, so needs adding to new_nodes here
|
||||
if (node.type === "unknown" || node._def.category !== "config") {
|
||||
if (node.type === 'junction') {
|
||||
new_junctions.push(node)
|
||||
} else if (node.type === "unknown" || node._def.category !== "config") {
|
||||
new_nodes.push(node);
|
||||
} else if (node.type === "group") {
|
||||
new_groups.push(node);
|
||||
@@ -2131,8 +2175,12 @@ RED.nodes = (function() {
|
||||
}
|
||||
|
||||
// Remap all wires and config node references
|
||||
for (i=0;i<new_nodes.length;i++) {
|
||||
n = new_nodes[i];
|
||||
for (i=0;i<new_nodes.length+new_junctions.length;i++) {
|
||||
if (i<new_nodes.length) {
|
||||
n = new_nodes[i];
|
||||
} else {
|
||||
n = new_junctions[i - new_nodes.length]
|
||||
}
|
||||
if (n.wires) {
|
||||
for (var w1=0;w1<n.wires.length;w1++) {
|
||||
var wires = (n.wires[w1] instanceof Array)?n.wires[w1]:[n.wires[w1]];
|
||||
@@ -2271,6 +2319,12 @@ RED.nodes = (function() {
|
||||
addGroup(n);
|
||||
}
|
||||
|
||||
for (i=0;i<new_junctions.length;i++) {
|
||||
var junction = new_junctions[i];
|
||||
addJunction(junction);
|
||||
}
|
||||
|
||||
|
||||
// Now the nodes have been fully updated, add them.
|
||||
for (i=0;i<new_nodes.length;i++) {
|
||||
var node = new_nodes[i];
|
||||
@@ -2301,6 +2355,7 @@ RED.nodes = (function() {
|
||||
nodes:new_nodes,
|
||||
links:new_links,
|
||||
groups:new_groups,
|
||||
junctions: new_junctions,
|
||||
workspaces:new_workspaces,
|
||||
subflows:new_subflows,
|
||||
missingWorkspace: missingWorkspace,
|
||||
@@ -2456,6 +2511,30 @@ RED.nodes = (function() {
|
||||
RED.events.emit("groups:remove",group);
|
||||
}
|
||||
|
||||
function addJunction(junction) {
|
||||
junctionsByZ[junction.z] = junctionsByZ[junction.z] || []
|
||||
junctionsByZ[junction.z].push(junction)
|
||||
junctions[junction.id] = junction;
|
||||
if (!nodeLinks[junction.id]) {
|
||||
nodeLinks[junction.id] = {in:[],out:[]};
|
||||
}
|
||||
RED.events.emit("junctions:add", junction)
|
||||
}
|
||||
function removeJunction(junction) {
|
||||
var i = junctionsByZ[junction.z].indexOf(junction)
|
||||
junctionsByZ[junction.z].splice(i, 1)
|
||||
if (junctionsByZ[junction.z].length === 0) {
|
||||
delete junctionsByZ[junction.z]
|
||||
}
|
||||
delete junctions[junction.id]
|
||||
delete nodeLinks[junction.id];
|
||||
RED.events.emit("junctions:remove", junction)
|
||||
|
||||
var removedLinks = links.filter(function(l) { return (l.source === junction) || (l.target === junction); });
|
||||
removedLinks.forEach(removeLink);
|
||||
return { links: removedLinks }
|
||||
}
|
||||
|
||||
function getNodeHelp(type) {
|
||||
var helpContent = "";
|
||||
var helpElement = $("script[data-help-name='"+type+"']");
|
||||
@@ -2684,7 +2763,6 @@ RED.nodes = (function() {
|
||||
getType: registry.getNodeType,
|
||||
getNodeHelp: getNodeHelp,
|
||||
convertNode: convertNode,
|
||||
|
||||
add: addNode,
|
||||
remove: removeNode,
|
||||
clear: clear,
|
||||
@@ -2730,6 +2808,11 @@ RED.nodes = (function() {
|
||||
group: function(id) { return groups[id] },
|
||||
groups: function(z) { return groupsByZ[z]?groupsByZ[z].slice():[] },
|
||||
|
||||
addJunction: addJunction,
|
||||
removeJunction: removeJunction,
|
||||
junction: function(id) { return junctions[id] },
|
||||
junctions: function(z) { return junctionsByZ[z]?junctionsByZ[z].slice():[] },
|
||||
|
||||
eachNode: function(cb) {
|
||||
allNodes.eachNode(cb);
|
||||
},
|
||||
|
||||
@@ -602,7 +602,10 @@ var RED = (function() {
|
||||
null,
|
||||
{id: "menu-item-edit-select-all", label:RED._("keyboard.selectAll"), onselect: "core:select-all-nodes"},
|
||||
{id: "menu-item-edit-select-connected", label:RED._("keyboard.selectAllConnected"), onselect: "core:select-connected-nodes"},
|
||||
{id: "menu-item-edit-select-none", label:RED._("keyboard.selectNone"), onselect: "core:select-none"}
|
||||
{id: "menu-item-edit-select-none", label:RED._("keyboard.selectNone"), onselect: "core:select-none"},
|
||||
null,
|
||||
{id: "menu-item-edit-split-wire-with-links", label:RED._("keyboard.splitWireWithLinks"), onselect: "core:split-wire-with-link-nodes"},
|
||||
|
||||
]});
|
||||
|
||||
menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[
|
||||
|
||||
@@ -987,6 +987,7 @@ RED.clipboard = (function() {
|
||||
try {
|
||||
RED.view.importNodes(newNodes, importOptions);
|
||||
} catch(error) {
|
||||
console.log(error.importConfig)
|
||||
// Thrown for import_conflict
|
||||
confirmImport(error.importConfig, newNodes, importOptions);
|
||||
}
|
||||
|
||||
@@ -352,8 +352,10 @@ RED.group = (function() {
|
||||
}
|
||||
if (n.type === 'group') {
|
||||
RED.events.emit("groups:change",n)
|
||||
} else {
|
||||
} else if (n.type !== 'junction') {
|
||||
RED.events.emit("nodes:change",n)
|
||||
} else {
|
||||
RED.events.emit("junctions:change",n)
|
||||
}
|
||||
})
|
||||
RED.nodes.removeGroup(g);
|
||||
@@ -547,8 +549,10 @@ RED.group = (function() {
|
||||
group.h = Math.max(group.h,n.y+n.h/2+25-group.y);
|
||||
if (n.type === 'group') {
|
||||
RED.events.emit("groups:change",n)
|
||||
} else {
|
||||
} else if (n.type !== 'junction') {
|
||||
RED.events.emit("nodes:change",n)
|
||||
} else {
|
||||
RED.events.emit("junctions:change",n)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -583,8 +587,10 @@ RED.group = (function() {
|
||||
}
|
||||
if (n.type === 'group') {
|
||||
RED.events.emit("groups:change",n)
|
||||
} else {
|
||||
} else if (n.type !== 'junction') {
|
||||
RED.events.emit("nodes:change",n)
|
||||
} else {
|
||||
RED.events.emit("junctions:change",n)
|
||||
}
|
||||
}
|
||||
markDirty(group);
|
||||
|
||||
@@ -224,14 +224,7 @@ RED.palette = (function() {
|
||||
|
||||
var d = $('<div>',{class:"red-ui-palette-node"}).attr("data-palette-type",nt).data('category',rootCategory);
|
||||
|
||||
var label = nt;///^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1];
|
||||
if (typeof def.paletteLabel !== "undefined") {
|
||||
try {
|
||||
label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||"";
|
||||
} catch(err) {
|
||||
console.log("Definition error: "+nt+".paletteLabel",err);
|
||||
}
|
||||
}
|
||||
var label = RED.utils.getPaletteLabel(nt, def);///^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1];
|
||||
|
||||
$('<div/>', {
|
||||
class: "red-ui-palette-label"+(((!def.align && def.inputs !== 0 && def.outputs === 0) || "right" === def.align) ? " red-ui-palette-label-right" : "")
|
||||
|
||||
@@ -25,6 +25,8 @@ RED.search = (function() {
|
||||
var searchHistory = [];
|
||||
var index = {};
|
||||
var currentResults = [];
|
||||
var activeResults = [];
|
||||
var currentIndex = 0;
|
||||
var previousActiveElement;
|
||||
|
||||
function indexProperty(node,label,property) {
|
||||
@@ -119,6 +121,7 @@ RED.search = (function() {
|
||||
val = extractFlag(val,"config",flags);
|
||||
val = extractFlag(val,"subflow",flags);
|
||||
val = extractFlag(val,"hidden",flags);
|
||||
val = extractFlag(val,"modified",flags);
|
||||
// uses:<node-id>
|
||||
val = extractValue(val,"uses",flags);
|
||||
|
||||
@@ -164,6 +167,11 @@ RED.search = (function() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (flags.hasOwnProperty("modified")) {
|
||||
if (!node.node.changed && !node.node.moved) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (flags.hasOwnProperty("hidden")) {
|
||||
// Only tabs can be hidden
|
||||
if (node.node.type !== 'tab') {
|
||||
@@ -261,9 +269,8 @@ RED.search = (function() {
|
||||
} else {
|
||||
searchResults.editableList('addItem',{});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
options: getSearchOptions()
|
||||
});
|
||||
var copySearchContainer = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-caret-right"></button>').appendTo(searchDiv).on('click', function(evt) {
|
||||
evt.preventDefault();
|
||||
@@ -324,7 +331,8 @@ RED.search = (function() {
|
||||
}
|
||||
} else if (!$(children[selected]).hasClass("red-ui-search-historyHeader")) {
|
||||
if (currentResults.length > 0) {
|
||||
reveal(currentResults[Math.max(0,selected)].node);
|
||||
currentIndex = Math.max(0,selected);
|
||||
reveal(currentResults[currentIndex].node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -408,6 +416,7 @@ RED.search = (function() {
|
||||
|
||||
div.on("click", function(evt) {
|
||||
evt.preventDefault();
|
||||
currentIndex = i;
|
||||
reveal(node);
|
||||
});
|
||||
}
|
||||
@@ -423,13 +432,59 @@ RED.search = (function() {
|
||||
if (existingIndex > -1) {
|
||||
searchHistory.splice(existingIndex,1);
|
||||
}
|
||||
searchHistory.unshift(searchInput.val());
|
||||
hide();
|
||||
searchHistory.unshift(searchVal);
|
||||
$("#red-ui-view-searchtools-search").data("term", searchVal);
|
||||
activeResults = Object.assign([], currentResults);
|
||||
hide(null, activeResults.length > 0);
|
||||
RED.view.reveal(node.id);
|
||||
}
|
||||
|
||||
function revealPrev() {
|
||||
if (disabled) {
|
||||
updateSearchToolbar();
|
||||
return;
|
||||
}
|
||||
if (!searchResults || !activeResults.length) {
|
||||
show();
|
||||
return;
|
||||
}
|
||||
if (currentIndex > 0) {
|
||||
currentIndex--;
|
||||
} else {
|
||||
currentIndex = activeResults.length - 1;
|
||||
}
|
||||
const n = activeResults[currentIndex];
|
||||
if (n && n.node && n.node.id) {
|
||||
RED.view.reveal(n.node.id);
|
||||
$("#red-ui-view-searchtools-prev").trigger("focus");
|
||||
}
|
||||
updateSearchToolbar();
|
||||
}
|
||||
function revealNext() {
|
||||
if (disabled) {
|
||||
updateSearchToolbar();
|
||||
return;
|
||||
}
|
||||
if (!searchResults || !activeResults.length) {
|
||||
show();
|
||||
return;
|
||||
}
|
||||
if (currentIndex < activeResults.length - 1) {
|
||||
currentIndex++
|
||||
} else {
|
||||
currentIndex = 0;
|
||||
}
|
||||
const n = activeResults[currentIndex];
|
||||
if (n && n.node && n.node.id) {
|
||||
RED.view.reveal(n.node.id);
|
||||
$("#red-ui-view-searchtools-next").trigger("focus");
|
||||
}
|
||||
updateSearchToolbar();
|
||||
}
|
||||
|
||||
function show(v) {
|
||||
if (disabled) {
|
||||
updateSearchToolbar();
|
||||
return;
|
||||
}
|
||||
if (!visible) {
|
||||
@@ -456,7 +511,7 @@ RED.search = (function() {
|
||||
searchInput.trigger("focus");
|
||||
}
|
||||
|
||||
function hide() {
|
||||
function hide(el, keepSearchToolbar) {
|
||||
if (visible) {
|
||||
visible = false;
|
||||
$("#red-ui-header-shade").hide();
|
||||
@@ -470,13 +525,37 @@ RED.search = (function() {
|
||||
});
|
||||
}
|
||||
RED.events.emit("search:close");
|
||||
if (previousActiveElement) {
|
||||
if (previousActiveElement && (!keepSearchToolbar || !activeResults.length)) {
|
||||
$(previousActiveElement).trigger("focus");
|
||||
previousActiveElement = null;
|
||||
}
|
||||
previousActiveElement = null;
|
||||
}
|
||||
if(!keepSearchToolbar) {
|
||||
clearActiveSearch();
|
||||
}
|
||||
updateSearchToolbar();
|
||||
if(keepSearchToolbar && activeResults.length) {
|
||||
$("#red-ui-view-searchtools-next").trigger("focus");
|
||||
}
|
||||
}
|
||||
function updateSearchToolbar() {
|
||||
if (!disabled && currentIndex >= 0 && activeResults && activeResults.length) {
|
||||
let term = $("#red-ui-view-searchtools-search").data("term") || "";
|
||||
if (term.length > 16) {
|
||||
term = term.substring(0, 12) + "..."
|
||||
}
|
||||
const i18nSearchCounterData = {
|
||||
term: term,
|
||||
result: (currentIndex + 1),
|
||||
count: activeResults.length
|
||||
}
|
||||
$("#red-ui-view-searchtools-counter").text(RED._('actions.search-counter', i18nSearchCounterData));
|
||||
$("#view-search-tools > :not(:first-child)").show(); //show other tools
|
||||
} else {
|
||||
clearActiveSearch();
|
||||
$("#view-search-tools > :not(:first-child)").hide(); //hide all but search button
|
||||
}
|
||||
}
|
||||
|
||||
function clearIndex() {
|
||||
index = {};
|
||||
}
|
||||
@@ -498,9 +577,29 @@ RED.search = (function() {
|
||||
addItemToIndex(item);
|
||||
}
|
||||
|
||||
function clearActiveSearch() {
|
||||
activeResults = [];
|
||||
currentIndex = 0;
|
||||
$("#red-ui-view-searchtools-search").data("term", "");
|
||||
}
|
||||
|
||||
function getSearchOptions() {
|
||||
return [
|
||||
{label:RED._("search.options.configNodes"), value:"is:config"},
|
||||
{label:RED._("search.options.unusedConfigNodes"), value:"is:config is:unused"},
|
||||
{label:RED._("search.options.modifiedNodes"), value:"is:modified"},
|
||||
{label:RED._("search.options.invalidNodes"), value: "is:invalid"},
|
||||
{label:RED._("search.options.uknownNodes"), value: "type:unknown"},
|
||||
{label:RED._("search.options.unusedSubflows"), value:"is:subflow is:unused"},
|
||||
{label:RED._("search.options.hiddenFlows"), value:"is:hidden"},
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
RED.actions.add("core:search",show);
|
||||
RED.actions.add("core:search-previous",revealPrev);
|
||||
RED.actions.add("core:search-next",revealNext);
|
||||
|
||||
RED.events.on("editor:open",function() { disabled = true; });
|
||||
RED.events.on("editor:close",function() { disabled = false; });
|
||||
@@ -511,11 +610,21 @@ RED.search = (function() {
|
||||
|
||||
RED.keyboard.add("red-ui-search","escape",hide);
|
||||
|
||||
RED.keyboard.add("view-search-tools","escape",function() {
|
||||
clearActiveSearch();
|
||||
updateSearchToolbar();
|
||||
});
|
||||
|
||||
$("#red-ui-header-shade").on('mousedown',hide);
|
||||
$("#red-ui-editor-shade").on('mousedown',hide);
|
||||
$("#red-ui-palette-shade").on('mousedown',hide);
|
||||
$("#red-ui-sidebar-shade").on('mousedown',hide);
|
||||
|
||||
$("#red-ui-view-searchtools-close").on("click", function close() {
|
||||
clearActiveSearch();
|
||||
updateSearchToolbar();
|
||||
});
|
||||
$("#red-ui-view-searchtools-close").trigger("click");
|
||||
|
||||
RED.events.on("workspace:clear", clearIndex);
|
||||
|
||||
@@ -541,7 +650,8 @@ RED.search = (function() {
|
||||
init: init,
|
||||
show: show,
|
||||
hide: hide,
|
||||
search: search
|
||||
search: search,
|
||||
getSearchOptions: getSearchOptions
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -29,5 +29,6 @@ RED.state = {
|
||||
GROUP_DRAGGING: 12,
|
||||
GROUP_RESIZE: 13,
|
||||
DETACHED_DRAGGING: 14,
|
||||
SLICING: 15
|
||||
SLICING: 15,
|
||||
SLICING_JUNCTION: 16
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ RED.statusBar = (function() {
|
||||
function addWidget(options) {
|
||||
widgets[options.id] = options;
|
||||
var el = $('<span class="red-ui-statusbar-widget"></span>');
|
||||
el.prop('id', options.id);
|
||||
options.element.appendTo(el);
|
||||
if (options.align === 'left') {
|
||||
leftBucket.append(el);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
**/
|
||||
RED.sidebar.config = (function() {
|
||||
|
||||
let flashingConfigNode;
|
||||
let flashingConfigNodeTimer;
|
||||
|
||||
var content = document.createElement("div");
|
||||
content.className = "red-ui-sidebar-node-config";
|
||||
@@ -145,6 +147,7 @@ RED.sidebar.config = (function() {
|
||||
var entry = $('<li class="red-ui-palette-node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list);
|
||||
var nodeDiv = $('<div class="red-ui-palette-node-config red-ui-palette-node"></div>').appendTo(entry);
|
||||
entry.data('node',node.id);
|
||||
nodeDiv.data('node',node.id);
|
||||
var label = $('<div class="red-ui-palette-label"></div>').text(label).appendTo(nodeDiv);
|
||||
if (node.d) {
|
||||
nodeDiv.addClass("red-ui-palette-node-config-disabled");
|
||||
@@ -350,6 +353,32 @@ RED.sidebar.config = (function() {
|
||||
RED.popover.tooltip($('#red-ui-sidebar-config-filter-unused'), RED._("sidebar.config.showAllUnusedConfigNodes"));
|
||||
|
||||
}
|
||||
|
||||
function flashConfigNode(el) {
|
||||
if(flashingConfigNode && flashingConfigNode.length) {
|
||||
//cancel current flashing node before flashing new node
|
||||
clearInterval(flashingConfigNodeTimer);
|
||||
flashingConfigNodeTimer = null;
|
||||
flashingConfigNode.children("div").removeClass('highlighted');
|
||||
flashingConfigNode = null;
|
||||
}
|
||||
if(!el || !el.children("div").length) { return; }
|
||||
|
||||
flashingConfigNodeTimer = setInterval(function(flashEndTime) {
|
||||
if (flashEndTime >= Date.now()) {
|
||||
const highlighted = el.children("div").hasClass("highlighted");
|
||||
el.children("div").toggleClass('highlighted', !highlighted)
|
||||
} else {
|
||||
clearInterval(flashingConfigNodeTimer);
|
||||
flashingConfigNodeTimer = null;
|
||||
flashingConfigNode = null;
|
||||
el.children("div").removeClass('highlighted');
|
||||
}
|
||||
}, 100, Date.now() + 2200);
|
||||
flashingConfigNode = el;
|
||||
el.children("div").addClass('highlighted');
|
||||
}
|
||||
|
||||
function show(id) {
|
||||
if (typeof id === 'boolean') {
|
||||
if (id) {
|
||||
@@ -374,19 +403,7 @@ RED.sidebar.config = (function() {
|
||||
} else if (y<0) {
|
||||
scrollWindow.animate({scrollTop: '+='+(y-10)},150);
|
||||
}
|
||||
var flash = 21;
|
||||
var flashFunc = function() {
|
||||
if ((flash%2)===0) {
|
||||
node.removeClass('node_highlighted');
|
||||
} else {
|
||||
node.addClass('node_highlighted');
|
||||
}
|
||||
flash--;
|
||||
if (flash >= 0) {
|
||||
setTimeout(flashFunc,100);
|
||||
}
|
||||
}
|
||||
flashFunc();
|
||||
flashConfigNode(node, id);
|
||||
},100);
|
||||
}
|
||||
RED.sidebar.show("config");
|
||||
|
||||
@@ -370,7 +370,7 @@ RED.sidebar.help = (function() {
|
||||
var node = selection.nodes[0];
|
||||
if (node.type === "subflow" && node.direction) {
|
||||
// ignore subflow virtual ports
|
||||
} else if (node.type !== 'group'){
|
||||
} else if (node.type !== 'group' && node.type !== 'junction'){
|
||||
showNodeTypeHelp(node.type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,14 +268,7 @@ RED.sidebar.info.outliner = (function() {
|
||||
|
||||
}
|
||||
},
|
||||
options: [
|
||||
{label:RED._("sidebar.info.search.configNodes"), value:"is:config"},
|
||||
{label:RED._("sidebar.info.search.unusedConfigNodes"), value:"is:config is:unused"},
|
||||
{label:RED._("sidebar.info.search.invalidNodes"), value: "is:invalid"},
|
||||
{label:RED._("sidebar.info.search.uknownNodes"), value: "type:unknown"},
|
||||
{label:RED._("sidebar.info.search.unusedSubflows"), value:"is:subflow is:unused"},
|
||||
{label:RED._("sidebar.info.search.hiddenFlows"), value:"is:hidden"},
|
||||
]
|
||||
options: RED.search.getSearchOptions()
|
||||
});
|
||||
|
||||
projectInfo = $('<div class="red-ui-treeList-label red-ui-info-outline-project"><span class="red-ui-treeList-icon"><i class="fa fa-archive"></i></span></div>').hide().appendTo(container)
|
||||
@@ -287,15 +280,18 @@ RED.sidebar.info.outliner = (function() {
|
||||
data:getFlowData()
|
||||
})
|
||||
treeList.on('treelistselect', function(e,item) {
|
||||
var node = RED.nodes.node(item.id) || RED.nodes.group(item.id);
|
||||
var node = RED.nodes.node(item.id) || RED.nodes.group(item.id) || RED.nodes.workspace(item.id) || RED.nodes.subflow(item.id);
|
||||
if (node) {
|
||||
if (node.type === 'group' || node._def.category !== "config") {
|
||||
// RED.view.select({nodes:[node]})
|
||||
} else if (node._def.category === "config") {
|
||||
RED.sidebar.info.refresh(node);
|
||||
} else {
|
||||
// RED.view.select({nodes:[]})
|
||||
}
|
||||
RED.sidebar.info.refresh(node);
|
||||
// if (node.type === 'group' || node._def.category !== "config") {
|
||||
// // RED.view.select({nodes:[node]})
|
||||
// } else if (node._def.category === "config") {
|
||||
// RED.sidebar.info.refresh(node);
|
||||
// } else {
|
||||
// // RED.view.select({nodes:[]})
|
||||
// }
|
||||
} else {
|
||||
RED.sidebar.info.refresh(null);
|
||||
}
|
||||
})
|
||||
treeList.on('treelistconfirm', function(e,item) {
|
||||
|
||||
@@ -163,6 +163,7 @@ RED.sidebar.info = (function() {
|
||||
});
|
||||
return el;
|
||||
}
|
||||
|
||||
function refresh(node) {
|
||||
if (node === undefined) {
|
||||
refreshSelection();
|
||||
@@ -271,7 +272,7 @@ RED.sidebar.info = (function() {
|
||||
objectType = "group";
|
||||
}
|
||||
$(propRow.children()[0]).text(RED._("sidebar.info."+objectType))
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
RED.utils.createObjectElement(node.id,{sourceId: node.id}).appendTo(propRow.children()[1]);
|
||||
|
||||
if (node.type === "tab" || node.type === "subflow") {
|
||||
// If nothing is selected, but we're on a flow or subflow tab.
|
||||
@@ -301,8 +302,8 @@ RED.sidebar.info = (function() {
|
||||
if (typeCounts.groups > 0) {
|
||||
$('<div>').text(RED._("clipboard.group",{count:typeCounts.groups})).appendTo(counts);
|
||||
}
|
||||
|
||||
|
||||
} else if (node.type === 'junction') {
|
||||
propertiesPanelHeaderHelp.hide();
|
||||
} else {
|
||||
propertiesPanelHeaderHelp.show();
|
||||
|
||||
@@ -365,7 +366,7 @@ RED.sidebar.info = (function() {
|
||||
|
||||
}
|
||||
} else {
|
||||
RED.utils.createObjectElement(val).appendTo(propRow.children()[1]);
|
||||
RED.utils.createObjectElement(val,{sourceId: node.id}).appendTo(propRow.children()[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -431,6 +432,7 @@ RED.sidebar.info = (function() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
function setInfoText(infoText,target) {
|
||||
var info = addTargetToExternalLinks($('<div class="red-ui-help"><span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(infoText)+'">'+infoText+'</span></div>')).appendTo(target);
|
||||
info.find(".red-ui-text-bidi-aware").contents().filter(function() { return this.nodeType === 3 && this.textContent.trim() !== "" }).wrap( "<span></span>" );
|
||||
@@ -447,6 +449,7 @@ RED.sidebar.info = (function() {
|
||||
$(this).toggleClass('expanded',!isExpanded);
|
||||
})
|
||||
}
|
||||
|
||||
var tips = (function() {
|
||||
var enabled = true;
|
||||
var startDelay = 1000;
|
||||
|
||||
@@ -171,17 +171,21 @@ RED.typeSearch = (function() {
|
||||
var div = $('<div>',{class:"red-ui-search-result"}).appendTo(container);
|
||||
|
||||
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div);
|
||||
var colour = RED.utils.getNodeColor(object.type,def);
|
||||
if (object.type === "junction") {
|
||||
nodeDiv.addClass("red-ui-palette-icon-junction");
|
||||
} else {
|
||||
var colour = RED.utils.getNodeColor(object.type,def);
|
||||
nodeDiv.css('backgroundColor',colour);
|
||||
}
|
||||
var icon_url = RED.utils.getNodeIcon(def);
|
||||
nodeDiv.css('backgroundColor',colour);
|
||||
|
||||
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
||||
RED.utils.createIconElement(icon_url, iconContainer, false);
|
||||
|
||||
if (def.inputs > 0) {
|
||||
if (object.type !== "junction" && def.inputs > 0) {
|
||||
$('<div/>',{class:"red-ui-search-result-node-port"}).appendTo(nodeDiv);
|
||||
}
|
||||
if (def.outputs > 0) {
|
||||
if (object.type !== "junction" && def.outputs > 0) {
|
||||
$('<div/>',{class:"red-ui-search-result-node-port red-ui-search-result-node-output"}).appendTo(nodeDiv);
|
||||
}
|
||||
|
||||
@@ -313,8 +317,8 @@ RED.typeSearch = (function() {
|
||||
return !filter ||
|
||||
(
|
||||
(!filter.type || type === filter.type) &&
|
||||
(!filter.input || def.inputs > 0) &&
|
||||
(!filter.output || def.outputs > 0)
|
||||
(!filter.input || type === 'junction' || def.inputs > 0) &&
|
||||
(!filter.output || type === 'junction' || def.outputs > 0)
|
||||
)
|
||||
}
|
||||
function refreshTypeList(opts) {
|
||||
@@ -323,7 +327,7 @@ RED.typeSearch = (function() {
|
||||
searchInput.searchBox('value','').focus();
|
||||
selected = -1;
|
||||
var common = [
|
||||
'inject','debug','function','change','switch'
|
||||
'inject','debug','function','change','switch','junction'
|
||||
].filter(function(t) { return applyFilter(opts.filter,t,RED.nodes.getType(t)); });
|
||||
|
||||
var recentlyUsed = Object.keys(typesUsed);
|
||||
@@ -348,6 +352,9 @@ RED.typeSearch = (function() {
|
||||
var index = 0;
|
||||
for(i=0;i<common.length;i++) {
|
||||
var itemDef = RED.nodes.getType(common[i]);
|
||||
if (common[i] === 'junction') {
|
||||
itemDef = { inputs:1, outputs: 1, label: 'junction', type: 'junction'}
|
||||
}
|
||||
if (itemDef) {
|
||||
item = {
|
||||
type: common[i],
|
||||
|
||||
@@ -365,7 +365,16 @@ RED.utils = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
function buildMessageElement(obj,options) {
|
||||
/**
|
||||
* Create a DOM element representation of obj - as used by Debug sidebar etc
|
||||
*
|
||||
* @params obj - the data to display
|
||||
* @params options - a bag of options
|
||||
*
|
||||
* - If you want the Copy Value button, then set `sourceId`
|
||||
* - If you want the Copy Path button, also set `path` to the value to be copied
|
||||
*/
|
||||
function createObjectElement(obj,options) {
|
||||
options = options || {};
|
||||
var key = options.key;
|
||||
var typeHint = options.typeHint;
|
||||
@@ -555,7 +564,7 @@ RED.utils = (function() {
|
||||
if (fullLength <= 10) {
|
||||
for (i=0;i<fullLength;i++) {
|
||||
row = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(arrayRows);
|
||||
subElements[path+"["+i+"]"] = buildMessageElement(
|
||||
subElements[path+"["+i+"]"] = createObjectElement(
|
||||
data[i],
|
||||
{
|
||||
key: ""+i,
|
||||
@@ -585,7 +594,7 @@ RED.utils = (function() {
|
||||
return function() {
|
||||
for (var i=min;i<=max;i++) {
|
||||
var row = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(parent);
|
||||
subElements[path+"["+i+"]"] = buildMessageElement(
|
||||
subElements[path+"["+i+"]"] = createObjectElement(
|
||||
data[i],
|
||||
{
|
||||
key: ""+i,
|
||||
@@ -641,7 +650,7 @@ RED.utils = (function() {
|
||||
newPath += "[\""+keys[i].replace(/"/,"\\\"")+"\"]"
|
||||
}
|
||||
}
|
||||
subElements[newPath] = buildMessageElement(
|
||||
subElements[newPath] = createObjectElement(
|
||||
data[keys[i]],
|
||||
{
|
||||
key: keys[i],
|
||||
@@ -1019,6 +1028,8 @@ RED.utils = (function() {
|
||||
return "font-awesome/fa-object-ungroup";
|
||||
} else if (node && node.type === 'group') {
|
||||
return "font-awesome/fa-object-group"
|
||||
} else if ((node && node.type === 'junction') || (def.type === "junction") ) {
|
||||
return "font-awesome/fa-circle-o"
|
||||
} else if (def.category === 'config') {
|
||||
return RED.settings.apiRootUrl+"icons/node-red/cog.svg"
|
||||
} else if (node && node.type === 'tab') {
|
||||
@@ -1084,6 +1095,8 @@ RED.utils = (function() {
|
||||
l = node.label || defaultLabel
|
||||
} else if (node.type === 'group') {
|
||||
l = node.name || defaultLabel
|
||||
} else if (node.type === 'junction') {
|
||||
l = 'junction'
|
||||
} else {
|
||||
l = node._def.label;
|
||||
try {
|
||||
@@ -1096,6 +1109,18 @@ RED.utils = (function() {
|
||||
return RED.text.bidi.enforceTextDirectionWithUCC(l);
|
||||
}
|
||||
|
||||
function getPaletteLabel(nodeType, def) {
|
||||
var label = nodeType;
|
||||
if (typeof def.paletteLabel !== "undefined") {
|
||||
try {
|
||||
label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||"";
|
||||
} catch(err) {
|
||||
console.log("Definition error: "+nodeType+".paletteLabel",err);
|
||||
}
|
||||
}
|
||||
return label
|
||||
}
|
||||
|
||||
var nodeColorCache = {};
|
||||
function clearNodeColorCache() {
|
||||
nodeColorCache = {};
|
||||
@@ -1238,6 +1263,8 @@ RED.utils = (function() {
|
||||
nodeDiv.addClass("red-ui-palette-icon-selection");
|
||||
} else if (node.type === "group") {
|
||||
nodeDiv.addClass("red-ui-palette-icon-group");
|
||||
} else if (node.type === "junction") {
|
||||
nodeDiv.addClass("red-ui-palette-icon-junction");
|
||||
} else if (node.type === 'tab') {
|
||||
nodeDiv.addClass("red-ui-palette-icon-flow");
|
||||
} else {
|
||||
@@ -1369,7 +1396,7 @@ RED.utils = (function() {
|
||||
}
|
||||
|
||||
return {
|
||||
createObjectElement: buildMessageElement,
|
||||
createObjectElement: createObjectElement,
|
||||
getMessageProperty: getMessageProperty,
|
||||
setMessageProperty: setMessageProperty,
|
||||
normalisePropertyExpression: normalisePropertyExpression,
|
||||
@@ -1379,6 +1406,7 @@ RED.utils = (function() {
|
||||
getNodeIcon: getNodeIcon,
|
||||
getNodeLabel: getNodeLabel,
|
||||
getNodeColor: getNodeColor,
|
||||
getPaletteLabel: getPaletteLabel,
|
||||
clearNodeColorCache: clearNodeColorCache,
|
||||
addSpinnerOverlay: addSpinnerOverlay,
|
||||
decodeObject: decodeObject,
|
||||
|
||||
@@ -809,6 +809,231 @@ RED.view.tools = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits selected wires and re-joins them with link-out+link-in
|
||||
* @param {Object || Object[]} wires The wire(s) to split and replace with link-out, link-in nodes.
|
||||
*/
|
||||
function splitWiresWithLinkNodes(wires) {
|
||||
let wiresToSplit = wires || RED.view.selection().links;
|
||||
if (!Array.isArray(wiresToSplit)) {
|
||||
wiresToSplit = [wiresToSplit];
|
||||
}
|
||||
if (wiresToSplit.length < 1) {
|
||||
return; //nothing selected
|
||||
}
|
||||
|
||||
const history = {
|
||||
t: 'multi',
|
||||
events: [],
|
||||
dirty: RED.nodes.dirty()
|
||||
}
|
||||
const nodeSrcMap = {};
|
||||
const nodeTrgMap = {};
|
||||
const _gridSize = RED.view.gridSize();
|
||||
|
||||
for (let wireIdx = 0; wireIdx < wiresToSplit.length; wireIdx++) {
|
||||
const wire = wiresToSplit[wireIdx];
|
||||
|
||||
//get source and target nodes of this wire link
|
||||
const nSrc = wire.source;
|
||||
const nTrg = wire.target;
|
||||
|
||||
var updateNewNodePosXY = function (origNode, newNode, alignLeft, snap, yOffset) {
|
||||
const nnSize = RED.view.calculateNodeDimensions(newNode);
|
||||
newNode.w = nnSize[0];
|
||||
newNode.h = nnSize[1];
|
||||
const coords = { x: origNode.x || 0, y: origNode.y || 0, w: origNode.w || RED.view.node_width, h: origNode.h || RED.view.node_height };
|
||||
const x = coords.x - (coords.w/2.0);
|
||||
if (alignLeft) {
|
||||
coords.x = x - _gridSize - (newNode.w/2.0);
|
||||
} else {
|
||||
coords.x = x + coords.w + _gridSize + (newNode.w/2.0);
|
||||
}
|
||||
newNode.x = coords.x;
|
||||
newNode.y = coords.y;
|
||||
if (snap !== false) {
|
||||
const offsets = RED.view.tools.calculateGridSnapOffsets(newNode);
|
||||
newNode.x -= offsets.x;
|
||||
newNode.y -= offsets.y;
|
||||
}
|
||||
newNode.y += (yOffset || 0);
|
||||
}
|
||||
const srcPort = (wire.sourcePort || 0);
|
||||
let linkOutMapId = nSrc.id + ':' + srcPort;
|
||||
let nnLinkOut = nodeSrcMap[linkOutMapId];
|
||||
//Create a Link Out if one is not already present
|
||||
if(!nnLinkOut) {
|
||||
const nLinkOut = RED.view.createNode("link out"); //create link node
|
||||
nnLinkOut = nLinkOut.node;
|
||||
nodeSrcMap[linkOutMapId] = nnLinkOut;
|
||||
let yOffset = 0;
|
||||
if(nSrc.outputs > 1) {
|
||||
|
||||
const CENTER_PORT = (((nSrc.outputs-1) / 2) + 1);
|
||||
const offsetCount = Math.abs(CENTER_PORT - (srcPort + 1));
|
||||
yOffset = (_gridSize * 2 * offsetCount);
|
||||
if((srcPort + 1) < CENTER_PORT) {
|
||||
yOffset = -yOffset;
|
||||
}
|
||||
updateNewNodePosXY(nSrc, nnLinkOut, false, false, yOffset);
|
||||
} else {
|
||||
updateNewNodePosXY(nSrc, nnLinkOut, false, RED.view.snapGrid, yOffset);
|
||||
}
|
||||
//add created node
|
||||
RED.nodes.add(nnLinkOut);
|
||||
RED.editor.validateNode(nnLinkOut);
|
||||
history.events.push(nLinkOut.historyEvent);
|
||||
//connect node to link node
|
||||
const link = {
|
||||
source: nSrc,
|
||||
sourcePort: wire.sourcePort || 0,
|
||||
target: nnLinkOut
|
||||
};
|
||||
RED.nodes.addLink(link);
|
||||
history.events.push({
|
||||
t: 'add',
|
||||
links: [link],
|
||||
});
|
||||
}
|
||||
|
||||
let nnLinkIn = nodeTrgMap[nTrg.id];
|
||||
//Create a Link In if one is not already present
|
||||
if(!nnLinkIn) {
|
||||
const nLinkIn = RED.view.createNode("link in"); //create link node
|
||||
nnLinkIn = nLinkIn.node;
|
||||
nodeTrgMap[nTrg.id] = nnLinkIn;
|
||||
updateNewNodePosXY(nTrg, nnLinkIn, true, RED.view.snapGrid, 0);
|
||||
//add created node
|
||||
RED.nodes.add(nnLinkIn);
|
||||
RED.editor.validateNode(nnLinkIn);
|
||||
history.events.push(nLinkIn.historyEvent);
|
||||
//connect node to link node
|
||||
const link = {
|
||||
source: nnLinkIn,
|
||||
sourcePort: 0,
|
||||
target: nTrg
|
||||
};
|
||||
RED.nodes.addLink(link);
|
||||
history.events.push({
|
||||
t: 'add',
|
||||
links: [link],
|
||||
});
|
||||
}
|
||||
|
||||
//connect the link out/link in virtual wires
|
||||
if(nnLinkIn.links.indexOf(nnLinkOut.id) == -1) {
|
||||
nnLinkIn.links.push(nnLinkOut.id);
|
||||
}
|
||||
if(nnLinkOut.links.indexOf(nnLinkIn.id) == -1) {
|
||||
nnLinkOut.links.push(nnLinkIn.id);
|
||||
}
|
||||
|
||||
//delete the original wire
|
||||
RED.nodes.removeLink(wire);
|
||||
history.events.push({
|
||||
t: "delete",
|
||||
links: [wire]
|
||||
});
|
||||
}
|
||||
//add all history events to stack
|
||||
RED.history.push(history);
|
||||
|
||||
//select all downstream of new link-in nodes so user can drag to new location
|
||||
RED.view.clearSelection();
|
||||
RED.view.select({nodes: Object.values(nodeTrgMap) });
|
||||
selectConnected("down");
|
||||
|
||||
//update the view
|
||||
RED.nodes.dirty(true);
|
||||
RED.view.redraw(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the required offsets to snap a node
|
||||
* @param {Object} node The node to calculate grid snap offsets for
|
||||
* @param {Object} [options] Options: `align` can be "nearest", "left" or "right"
|
||||
* @returns `{x:number, y:number}` as the offsets to deduct from `x` and `y`
|
||||
*/
|
||||
function calculateGridSnapOffsets(node, options) {
|
||||
options = options || { align: "nearest" };
|
||||
const gridOffset = { x: 0, y: 0 };
|
||||
const gridSize = RED.view.gridSize();
|
||||
const offsetLeft = node.x - (gridSize * Math.round((node.x - node.w / 2) / gridSize) + node.w / 2);
|
||||
const offsetRight = node.x - (gridSize * Math.round((node.x + node.w / 2) / gridSize) - node.w / 2);
|
||||
gridOffset.x = offsetRight;
|
||||
if (options.align === "right") {
|
||||
//skip - already set to right
|
||||
} else if (options.align === "left" || Math.abs(offsetLeft) < Math.abs(offsetRight)) {
|
||||
gridOffset.x = offsetLeft;
|
||||
}
|
||||
gridOffset.y = node.y - (gridSize * Math.round(node.y / gridSize));
|
||||
return gridOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate names for the select nodes.
|
||||
* - it only sets the name if it is currently blank
|
||||
* - it uses `<paletteLabel> <N>` - where N is the next available integer that
|
||||
* doesn't clash with any existing nodes of that type
|
||||
* @param {Object} node The node to set the name of - if not provided, uses current selection
|
||||
*/
|
||||
function generateNodeNames(node) {
|
||||
const nodes = node?[node]:RED.view.selection().nodes;
|
||||
if (nodes && nodes.length > 0) {
|
||||
// Generate history event if using the workspace selection,
|
||||
// or if the provided node already exists
|
||||
const generateHistory = !node || !!RED.nodes.node(node.id)
|
||||
const historyEvents = []
|
||||
const typeIndex = {}
|
||||
let changed = false;
|
||||
nodes.forEach(n => {
|
||||
if (n._def && n._def.defaults && n._def.defaults.name) {
|
||||
const paletteLabel = RED.utils.getPaletteLabel(n.type, n._def)
|
||||
const defaultNodeNameRE = new RegExp('^'+paletteLabel+' (\\d+)$')
|
||||
if (!typeIndex.hasOwnProperty(n.type)) {
|
||||
const existingNodes = RED.nodes.filterNodes({type: n.type})
|
||||
let maxNameNumber = 0;
|
||||
existingNodes.forEach(n => {
|
||||
let match = defaultNodeNameRE.exec(n.name)
|
||||
if (match) {
|
||||
let nodeNumber = parseInt(match[1])
|
||||
if (nodeNumber > maxNameNumber) {
|
||||
maxNameNumber = nodeNumber
|
||||
}
|
||||
}
|
||||
})
|
||||
typeIndex[n.type] = maxNameNumber + 1
|
||||
}
|
||||
if (n.name === '') {
|
||||
if (generateHistory) {
|
||||
historyEvents.push({
|
||||
t:'edit',
|
||||
node: n,
|
||||
changes: { name: n.name },
|
||||
dirty: RED.nodes.dirty(),
|
||||
changed: n.changed
|
||||
})
|
||||
}
|
||||
n.name = paletteLabel+" "+typeIndex[n.type]
|
||||
n.dirty = true
|
||||
typeIndex[n.type]++
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
})
|
||||
if (changed) {
|
||||
if (historyEvents.length > 0) {
|
||||
RED.history.push({
|
||||
t: 'multi',
|
||||
events: historyEvents
|
||||
})
|
||||
}
|
||||
RED.nodes.dirty(true)
|
||||
RED.view.redraw()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); })
|
||||
@@ -870,6 +1095,10 @@ RED.view.tools = (function() {
|
||||
RED.actions.add("core:wire-series-of-nodes", function() { wireSeriesOfNodes() })
|
||||
RED.actions.add("core:wire-node-to-multiple", function() { wireNodeToMultiple() })
|
||||
|
||||
RED.actions.add("core:split-wire-with-link-nodes", function () { splitWiresWithLinkNodes() });
|
||||
|
||||
RED.actions.add("core:generate-node-names", generateNodeNames )
|
||||
|
||||
// RED.actions.add("core:add-node", function() { addNode() })
|
||||
},
|
||||
/**
|
||||
@@ -881,7 +1110,8 @@ RED.view.tools = (function() {
|
||||
* @param {Number} dx
|
||||
* @param {Number} dy
|
||||
*/
|
||||
moveSelection: moveSelection
|
||||
moveSelection: moveSelection,
|
||||
calculateGridSnapOffsets: calculateGridSnapOffsets
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
* |- <g> "groupLayer"
|
||||
* |- <g> "groupSelectLayer"
|
||||
* |- <g> "linkLayer"
|
||||
* |- <g> "junctionLayer"
|
||||
* |- <g> "dragGroupLayer"
|
||||
* |- <g> "nodeLayer"
|
||||
*/
|
||||
@@ -56,6 +57,7 @@ RED.view = (function() {
|
||||
var activeSubflow = null;
|
||||
var activeNodes = [];
|
||||
var activeLinks = [];
|
||||
var activeJunctions = [];
|
||||
var activeFlowLinks = [];
|
||||
var activeLinkNodes = {};
|
||||
var activeGroup = null;
|
||||
@@ -90,6 +92,9 @@ RED.view = (function() {
|
||||
var lastClickPosition = [];
|
||||
var selectNodesOptions;
|
||||
|
||||
let flashingNodeId;
|
||||
let flashingNodeTimer;
|
||||
|
||||
var clipboard = "";
|
||||
|
||||
// Note: these are the permitted status colour aliases. The actual RGB values
|
||||
@@ -111,6 +116,7 @@ RED.view = (function() {
|
||||
var eventLayer;
|
||||
var gridLayer;
|
||||
var linkLayer;
|
||||
var junctionLayer;
|
||||
var dragGroupLayer;
|
||||
var groupSelectLayer;
|
||||
var nodeLayer;
|
||||
@@ -199,6 +205,11 @@ RED.view = (function() {
|
||||
|
||||
function init() {
|
||||
|
||||
// setTimeout(function() {
|
||||
// function snap(p) { return RED.view.gridSize() * Math.round(p/RED.view.gridSize())}; for (var i = 0;i<10;i++) {
|
||||
// RED.nodes.addJunction({_def:{defaults:{}}, type:'junction', z:"0ccdc1d81f2729cc",id:RED.nodes.id(),x:snap(Math.floor(Math.random()*600)),y:snap(Math.floor(Math.random()*600)), w:0,h:0})
|
||||
// } ; RED.view.redraw(true)
|
||||
// },2000)
|
||||
chart = $("#red-ui-workspace-chart");
|
||||
|
||||
outer = d3.select("#red-ui-workspace-chart")
|
||||
@@ -373,6 +384,7 @@ RED.view = (function() {
|
||||
groupSelectLayer = eventLayer.append("g");
|
||||
linkLayer = eventLayer.append("g");
|
||||
dragGroupLayer = eventLayer.append("g");
|
||||
junctionLayer = eventLayer.append("g");
|
||||
nodeLayer = eventLayer.append("g");
|
||||
|
||||
drag_lines = [];
|
||||
@@ -443,13 +455,40 @@ RED.view = (function() {
|
||||
}
|
||||
});
|
||||
|
||||
//add search to status-toolbar
|
||||
RED.statusBar.add({
|
||||
id: "view-search-tools",
|
||||
align: "left",
|
||||
hidden: false,
|
||||
element: $('<span class="button-group">'+
|
||||
'<button class="red-ui-footer-button" id="red-ui-view-searchtools-search"><i class="fa fa-search"></i></button>' +
|
||||
'</span>' +
|
||||
'<span class="button-group search-counter">' +
|
||||
'<span class="red-ui-footer-button" id="red-ui-view-searchtools-counter">? of ?</span>' +
|
||||
'</span>' +
|
||||
'<span class="button-group">' +
|
||||
'<button class="red-ui-footer-button" id="red-ui-view-searchtools-prev"><i class="fa fa-chevron-left"></i></button>' +
|
||||
'<button class="red-ui-footer-button" id="red-ui-view-searchtools-next"><i class="fa fa-chevron-right"></i></button>' +
|
||||
'</span>' +
|
||||
'<span class="button-group">' +
|
||||
'<button class="red-ui-footer-button" id="red-ui-view-searchtools-close"><i class="fa fa-close"></i></button>' +
|
||||
'</span>')
|
||||
})
|
||||
$("#red-ui-view-searchtools-search").on("click", searchFlows);
|
||||
RED.popover.tooltip($("#red-ui-view-searchtools-search"),RED._('actions.search-flows'),'core:search');
|
||||
$("#red-ui-view-searchtools-prev").on("click", searchPrev);
|
||||
RED.popover.tooltip($("#red-ui-view-searchtools-prev"),RED._('actions.search-prev'),'core:search-previous');
|
||||
$("#red-ui-view-searchtools-next").on("click", searchNext);
|
||||
RED.popover.tooltip($("#red-ui-view-searchtools-next"),RED._('actions.search-next'),'core:search-next');
|
||||
RED.popover.tooltip($("#red-ui-view-searchtools-close"),RED._('common.label.close'));
|
||||
|
||||
// Handle nodes dragged from the palette
|
||||
chart.droppable({
|
||||
accept:".red-ui-palette-node",
|
||||
drop: function( event, ui ) {
|
||||
d3.event = event;
|
||||
var selected_tool = $(ui.draggable[0]).attr("data-palette-type");
|
||||
var result = addNode(selected_tool);
|
||||
var result = createNode(selected_tool);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
@@ -493,17 +532,9 @@ RED.view = (function() {
|
||||
nn.y = mousePos[1];
|
||||
|
||||
if (snapGrid) {
|
||||
var gridOffset = [0,0];
|
||||
var offsetLeft = nn.x-(gridSize*Math.round((nn.x-nn.w/2)/gridSize)+nn.w/2);
|
||||
var offsetRight = nn.x-(gridSize*Math.round((nn.x+nn.w/2)/gridSize)-nn.w/2);
|
||||
if (Math.abs(offsetLeft) < Math.abs(offsetRight)) {
|
||||
gridOffset[0] = offsetLeft
|
||||
} else {
|
||||
gridOffset[0] = offsetRight
|
||||
}
|
||||
gridOffset[1] = nn.y-(gridSize*Math.round(nn.y/gridSize));
|
||||
nn.x -= gridOffset[0];
|
||||
nn.y -= gridOffset[1];
|
||||
var gridOffset = RED.view.tools.calculateGridSnapOffsets(nn);
|
||||
nn.x -= gridOffset.x;
|
||||
nn.y -= gridOffset.y;
|
||||
}
|
||||
|
||||
var spliceLink = $(ui.helper).data("splice");
|
||||
@@ -793,7 +824,7 @@ RED.view = (function() {
|
||||
source:{z:activeWorkspace},
|
||||
target:{z:activeWorkspace}
|
||||
});
|
||||
|
||||
activeJunctions = RED.nodes.junctions(activeWorkspace) || [];
|
||||
activeGroups = RED.nodes.groups(activeWorkspace)||[];
|
||||
activeGroups.forEach(function(g, i) {
|
||||
g._index = i;
|
||||
@@ -808,6 +839,7 @@ RED.view = (function() {
|
||||
} else {
|
||||
activeNodes = [];
|
||||
activeLinks = [];
|
||||
activeJunctions = [];
|
||||
activeGroups = [];
|
||||
}
|
||||
|
||||
@@ -927,81 +959,6 @@ RED.view = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
function addNode(type,x,y) {
|
||||
var m = /^subflow:(.+)$/.exec(type);
|
||||
|
||||
if (activeSubflow && m) {
|
||||
var subflowId = m[1];
|
||||
if (subflowId === activeSubflow.id) {
|
||||
RED.notify(RED._("notification.error",{message: RED._("notification.errors.cannotAddSubflowToItself")}),"error");
|
||||
return;
|
||||
}
|
||||
if (RED.nodes.subflowContains(m[1],activeSubflow.id)) {
|
||||
RED.notify(RED._("notification.error",{message: RED._("notification.errors.cannotAddCircularReference")}),"error");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var nn = { id:RED.nodes.id(),z:RED.workspaces.active()};
|
||||
|
||||
nn.type = type;
|
||||
nn._def = RED.nodes.getType(nn.type);
|
||||
|
||||
if (!m) {
|
||||
nn.inputs = nn._def.inputs || 0;
|
||||
nn.outputs = nn._def.outputs;
|
||||
|
||||
for (var d in nn._def.defaults) {
|
||||
if (nn._def.defaults.hasOwnProperty(d)) {
|
||||
if (nn._def.defaults[d].value !== undefined) {
|
||||
nn[d] = JSON.parse(JSON.stringify(nn._def.defaults[d].value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nn._def.onadd) {
|
||||
try {
|
||||
nn._def.onadd.call(nn);
|
||||
} catch(err) {
|
||||
console.log("Definition error: "+nn.type+".onadd:",err);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var subflow = RED.nodes.subflow(m[1]);
|
||||
nn.name = "";
|
||||
nn.inputs = subflow.in.length;
|
||||
nn.outputs = subflow.out.length;
|
||||
}
|
||||
|
||||
nn.changed = true;
|
||||
nn.moved = true;
|
||||
|
||||
nn.w = node_width;
|
||||
nn.h = Math.max(node_height,(nn.outputs||0) * 15);
|
||||
nn.resize = true;
|
||||
|
||||
var historyEvent = {
|
||||
t:"add",
|
||||
nodes:[nn.id],
|
||||
dirty:RED.nodes.dirty()
|
||||
}
|
||||
if (activeSubflow) {
|
||||
var subflowRefresh = RED.subflow.refresh(true);
|
||||
if (subflowRefresh) {
|
||||
historyEvent.subflow = {
|
||||
id:activeSubflow.id,
|
||||
changed: activeSubflow.changed,
|
||||
instances: subflowRefresh.instances
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
node: nn,
|
||||
historyEvent: historyEvent
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function canvasMouseDown() {
|
||||
if (RED.view.DEBUG) { console.warn("canvasMouseDown", mouse_mode); }
|
||||
var point;
|
||||
@@ -1053,9 +1010,9 @@ RED.view = (function() {
|
||||
.attr("class","nr-ui-view-lasso");
|
||||
d3.event.preventDefault();
|
||||
}
|
||||
} else if (mouse_mode === 0 && d3.event.button === 2 && (d3.event.metaKey || d3.event.ctrlKey)) {
|
||||
} else if (mouse_mode === 0 && d3.event.button === 2 && (d3.event.metaKey || d3.event.ctrlKey || d3.event.shiftKey)) {
|
||||
clearSelection();
|
||||
mouse_mode = RED.state.SLICING;
|
||||
mouse_mode = (d3.event.metaKey || d3.event.ctrlKey)?RED.state.SLICING : RED.state.SLICING_JUNCTION;
|
||||
point = d3.mouse(this);
|
||||
slicePath = eventLayer.append("path").attr("class","nr-ui-view-slice").attr("d",`M${point[0]} ${point[1]}`)
|
||||
slicePathLast = point;
|
||||
@@ -1190,16 +1147,38 @@ RED.view = (function() {
|
||||
keepAdding = false;
|
||||
resetMouseVars();
|
||||
}
|
||||
var result = addNode(type);
|
||||
if (!result) {
|
||||
return;
|
||||
|
||||
var nn;
|
||||
var historyEvent;
|
||||
if (type === 'junction') {
|
||||
nn = {
|
||||
_def: {defaults:{}},
|
||||
type: 'junction',
|
||||
z: RED.workspaces.active(),
|
||||
id: RED.nodes.id(),
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 0, h: 0,
|
||||
outputs: 1,
|
||||
inputs: 1,
|
||||
dirty: true
|
||||
}
|
||||
historyEvent = {
|
||||
t:'add',
|
||||
junctions:[nn]
|
||||
}
|
||||
} else {
|
||||
var result = createNode(type);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
nn = result.node;
|
||||
historyEvent = result.historyEvent;
|
||||
}
|
||||
if (keepAdding) {
|
||||
mouse_mode = RED.state.QUICK_JOINING;
|
||||
}
|
||||
|
||||
var nn = result.node;
|
||||
var historyEvent = result.historyEvent;
|
||||
nn.x = point[0];
|
||||
nn.y = point[1];
|
||||
var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
|
||||
@@ -1308,8 +1287,11 @@ RED.view = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RED.nodes.add(nn);
|
||||
if (nn.type === 'junction') {
|
||||
RED.nodes.addJunction(nn);
|
||||
} else {
|
||||
RED.nodes.add(nn);
|
||||
}
|
||||
RED.editor.validateNode(nn);
|
||||
|
||||
if (targetGroup) {
|
||||
@@ -1456,7 +1438,7 @@ RED.view = (function() {
|
||||
.attr("height",h)
|
||||
;
|
||||
return;
|
||||
} else if (mouse_mode === RED.state.SLICING) {
|
||||
} else if (mouse_mode === RED.state.SLICING || mouse_mode === RED.state.SLICING_JUNCTION) {
|
||||
if (slicePath) {
|
||||
var delta = Math.max(1,Math.abs(slicePathLast[0]-mouse_position[0]))*Math.max(1,Math.abs(slicePathLast[1]-mouse_position[1]))
|
||||
if (delta > 20) {
|
||||
@@ -1643,16 +1625,9 @@ RED.view = (function() {
|
||||
gridOffset[0] = node.n.x-(gridSize*Math.floor(node.n.x/gridSize))-gridSize/2;
|
||||
gridOffset[1] = node.n.y-(gridSize*Math.floor(node.n.y/gridSize))-gridSize/2;
|
||||
} else {
|
||||
var offsetLeft = node.n.x-(gridSize*Math.round((node.n.x-node.n.w/2)/gridSize)+node.n.w/2);
|
||||
var offsetRight = node.n.x-(gridSize*Math.round((node.n.x+node.n.w/2)/gridSize)-node.n.w/2);
|
||||
// gridOffset[0] = node.n.x-(gridSize*Math.floor((node.n.x-node.n.w/2)/gridSize)+node.n.w/2);
|
||||
if (Math.abs(offsetLeft) < Math.abs(offsetRight)) {
|
||||
gridOffset[0] = offsetLeft
|
||||
} else {
|
||||
gridOffset[0] = offsetRight
|
||||
}
|
||||
gridOffset[1] = node.n.y-(gridSize*Math.round(node.n.y/gridSize));
|
||||
// console.log(offsetLeft, offsetRight);
|
||||
const snapOffsets = RED.view.tools.calculateGridSnapOffsets(node.n);
|
||||
gridOffset[0] = snapOffsets.x;
|
||||
gridOffset[1] = snapOffsets.y;
|
||||
}
|
||||
if (gridOffset[0] !== 0 || gridOffset[1] !== 0) {
|
||||
for (i = 0; i<movingSet.length(); i++) {
|
||||
@@ -1829,6 +1804,15 @@ RED.view = (function() {
|
||||
}
|
||||
}
|
||||
});
|
||||
activeJunctions.forEach(function(n) {
|
||||
if (!n.selected) {
|
||||
if (n.x > x && n.x < x2 && n.y > y && n.y < y2) {
|
||||
n.selected = true;
|
||||
n.dirty = true;
|
||||
movingSet.add(n);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -1872,11 +1856,92 @@ RED.view = (function() {
|
||||
} else if (mouse_mode == RED.state.DEFAULT && mousedown_link == null && !d3.event.ctrlKey && !d3.event.metaKey ) {
|
||||
clearSelection();
|
||||
updateSelection();
|
||||
} else if (slicePath) {
|
||||
} else if (mouse_mode == RED.state.SLICING) {
|
||||
deleteSelection();
|
||||
slicePath.remove();
|
||||
slicePath = null;
|
||||
RED.view.redraw(true);
|
||||
} else if (mouse_mode == RED.state.SLICING_JUNCTION) {
|
||||
var removedLinks = []
|
||||
var addedLinks = []
|
||||
var addedJunctions = []
|
||||
|
||||
var groupedLinks = {}
|
||||
selectedLinks.forEach(function(l) {
|
||||
var sourceId = l.source.id+":"+l.sourcePort
|
||||
groupedLinks[sourceId] = groupedLinks[sourceId] || []
|
||||
groupedLinks[sourceId].push(l)
|
||||
});
|
||||
var linkGroups = Object.keys(groupedLinks)
|
||||
linkGroups.forEach(function(gid) {
|
||||
var links = groupedLinks[gid]
|
||||
var junction = {
|
||||
_def: {defaults:{}},
|
||||
type: 'junction',
|
||||
z: RED.workspaces.active(),
|
||||
id: RED.nodes.id(),
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 0, h: 0,
|
||||
outputs: 1,
|
||||
inputs: 1,
|
||||
dirty: true
|
||||
}
|
||||
links.forEach(function(l) {
|
||||
junction.x += l._sliceLocation.x
|
||||
junction.y += l._sliceLocation.y
|
||||
})
|
||||
junction.x = Math.round(junction.x/links.length)
|
||||
junction.y = Math.round(junction.y/links.length)
|
||||
if (snapGrid) {
|
||||
junction.x = (gridSize*Math.round(junction.x/gridSize));
|
||||
junction.y = (gridSize*Math.round(junction.y/gridSize));
|
||||
}
|
||||
|
||||
var nodeGroups = new Set()
|
||||
|
||||
RED.nodes.addJunction(junction)
|
||||
addedJunctions.push(junction)
|
||||
var newLink = {
|
||||
source: links[0].source,
|
||||
sourcePort: links[0].sourcePort,
|
||||
target: junction
|
||||
}
|
||||
addedLinks.push(newLink)
|
||||
RED.nodes.addLink(newLink)
|
||||
links.forEach(function(l) {
|
||||
removedLinks.push(l)
|
||||
RED.nodes.removeLink(l)
|
||||
var newLink = {
|
||||
source: junction,
|
||||
sourcePort: 0,
|
||||
target: l.target
|
||||
}
|
||||
addedLinks.push(newLink)
|
||||
RED.nodes.addLink(newLink)
|
||||
nodeGroups.add(l.source.g || "__NONE__")
|
||||
nodeGroups.add(l.target.g || "__NONE__")
|
||||
})
|
||||
if (nodeGroups.size === 1) {
|
||||
var group = nodeGroups.values().next().value
|
||||
if (group !== "__NONE__") {
|
||||
RED.group.addToGroup(RED.nodes.group(group), junction)
|
||||
}
|
||||
}
|
||||
})
|
||||
slicePath.remove();
|
||||
slicePath = null;
|
||||
|
||||
if (addedJunctions.length > 0) {
|
||||
RED.history.push({
|
||||
t: 'add',
|
||||
links: addedLinks,
|
||||
junctions: addedJunctions,
|
||||
removedLinks: removedLinks
|
||||
})
|
||||
RED.nodes.dirty(true)
|
||||
}
|
||||
RED.view.redraw(true);
|
||||
}
|
||||
if (mouse_mode == RED.state.MOVING_ACTIVE) {
|
||||
if (movingSet.length() > 0) {
|
||||
@@ -1997,6 +2062,9 @@ RED.view = (function() {
|
||||
}
|
||||
}
|
||||
function zoomZero() { zoomView(1); }
|
||||
function searchFlows() { RED.actions.invoke("core:search", $(this).data("term")); }
|
||||
function searchPrev() { RED.actions.invoke("core:search-previous"); }
|
||||
function searchNext() { RED.actions.invoke("core:search-next"); }
|
||||
|
||||
|
||||
function zoomView(factor) {
|
||||
@@ -2033,7 +2101,7 @@ RED.view = (function() {
|
||||
clearSelection();
|
||||
RED.history.pop();
|
||||
mouse_mode = 0;
|
||||
} else if (mouse_mode === RED.state.SLICING) {
|
||||
} else if (mouse_mode === RED.state.SLICING || mouse_mode === RED.state.SLICING_JUNCTION) {
|
||||
if (slicePath) {
|
||||
slicePath.remove();
|
||||
slicePath = null;
|
||||
@@ -2102,6 +2170,14 @@ RED.view = (function() {
|
||||
}
|
||||
});
|
||||
|
||||
activeJunctions.forEach(function(n) {
|
||||
if (!n.selected) {
|
||||
n.selected = true;
|
||||
n.dirty = true;
|
||||
movingSet.add(n);
|
||||
}
|
||||
})
|
||||
|
||||
if (mouse_mode !== RED.state.SELECTING_NODE && activeSubflow) {
|
||||
activeSubflow.in.forEach(function(n) {
|
||||
if (!n.selected) {
|
||||
@@ -2301,6 +2377,7 @@ RED.view = (function() {
|
||||
nodes: [],
|
||||
links: [],
|
||||
groups: [],
|
||||
junctions: [],
|
||||
workspaces: [],
|
||||
subflows: []
|
||||
}
|
||||
@@ -2321,6 +2398,7 @@ RED.view = (function() {
|
||||
historyEvent.nodes = historyEvent.nodes.concat(subEvent.nodes);
|
||||
historyEvent.links = historyEvent.links.concat(subEvent.links);
|
||||
historyEvent.groups = historyEvent.groups.concat(subEvent.groups);
|
||||
historyEvent.junctions = historyEvent.junctions.concat(subEvent.junctions);
|
||||
}
|
||||
RED.history.push(historyEvent);
|
||||
RED.nodes.dirty(true);
|
||||
@@ -2333,6 +2411,7 @@ RED.view = (function() {
|
||||
var removedNodes = [];
|
||||
var removedLinks = [];
|
||||
var removedGroups = [];
|
||||
var removedJunctions = [];
|
||||
var removedSubflowOutputs = [];
|
||||
var removedSubflowInputs = [];
|
||||
var removedSubflowStatus;
|
||||
@@ -2377,7 +2456,7 @@ RED.view = (function() {
|
||||
for (var i=0;i<movingSet.length();i++) {
|
||||
node = movingSet.get(i).n;
|
||||
node.selected = false;
|
||||
if (node.type !== "group" && node.type !== "subflow") {
|
||||
if (node.type !== "group" && node.type !== "subflow" && node.type !== 'junction') {
|
||||
if (node.x < 0) {
|
||||
node.x = 25
|
||||
}
|
||||
@@ -2395,6 +2474,10 @@ RED.view = (function() {
|
||||
RED.group.markDirty(group);
|
||||
}
|
||||
}
|
||||
} else if (node.type === 'junction') {
|
||||
var result = RED.nodes.removeJunction(node)
|
||||
removedJunctions.push(node);
|
||||
removedLinks = removedLinks.concat(result.links);
|
||||
} else {
|
||||
if (node.direction === "out") {
|
||||
removedSubflowOutputs.push(node);
|
||||
@@ -2439,7 +2522,7 @@ RED.view = (function() {
|
||||
subflowInstances = instances.instances;
|
||||
}
|
||||
movingSet.clear();
|
||||
if (removedNodes.length > 0 || removedSubflowOutputs.length > 0 || removedSubflowInputs.length > 0 || removedSubflowStatus || removedGroups.length > 0) {
|
||||
if (removedNodes.length > 0 || removedSubflowOutputs.length > 0 || removedSubflowInputs.length > 0 || removedSubflowStatus || removedGroups.length > 0 || removedJunctions.length > 0) {
|
||||
RED.nodes.dirty(true);
|
||||
}
|
||||
}
|
||||
@@ -2486,6 +2569,7 @@ RED.view = (function() {
|
||||
nodes:removedNodes,
|
||||
links:removedLinks,
|
||||
groups: removedGroups,
|
||||
junctions: removedJunctions,
|
||||
subflowOutputs:removedSubflowOutputs,
|
||||
subflowInputs:removedSubflowInputs,
|
||||
subflow: {
|
||||
@@ -2545,6 +2629,7 @@ RED.view = (function() {
|
||||
var nns = [];
|
||||
var nodeCount = 0;
|
||||
var groupCount = 0;
|
||||
var junctionCount = 0;
|
||||
var handled = {};
|
||||
for (var n=0;n<nodes.length;n++) {
|
||||
var node = nodes[n];
|
||||
@@ -2557,6 +2642,8 @@ RED.view = (function() {
|
||||
if (node.type != "subflow") {
|
||||
if (node.type === "group") {
|
||||
groupCount++;
|
||||
} else if (node.type === 'junction') {
|
||||
junctionCount++;
|
||||
} else {
|
||||
nodeCount++;
|
||||
}
|
||||
@@ -2739,6 +2826,7 @@ RED.view = (function() {
|
||||
evt.preventDefault();
|
||||
}
|
||||
|
||||
|
||||
function portMouseUp(d,portType,portIndex,evt) {
|
||||
if (RED.view.DEBUG) { console.warn("portMouseUp", mouse_mode,d,portType,portIndex); }
|
||||
evt = evt || d3.event;
|
||||
@@ -3121,6 +3209,52 @@ RED.view = (function() {
|
||||
port.classed("red-ui-flow-port-hovered",false);
|
||||
}
|
||||
|
||||
function junctionMouseOver(junction, d) {
|
||||
junction.classed("red-ui-flow-junction-hovered",true);
|
||||
}
|
||||
function junctionMouseOut(junction, d) {
|
||||
junction.classed("red-ui-flow-junction-hovered",false);
|
||||
}
|
||||
|
||||
function junctionMouseDown(junction, d, evt) {
|
||||
if (RED.view.DEBUG) { console.warn("junctionMouseDown", d); }
|
||||
evt = evt || d3.event;
|
||||
d3.event = evt
|
||||
if (evt === 1) {
|
||||
return;
|
||||
}
|
||||
if (mouse_mode === RED.state.SELECTING_NODE) {
|
||||
evt.stopPropagation();
|
||||
return;
|
||||
}
|
||||
if (mouse_mode == RED.state.QUICK_JOINING) {
|
||||
d3.event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
// mousedown_node = d;
|
||||
// mousedown_port_type = portType;
|
||||
// mousedown_port_index = portIndex || 0;
|
||||
if (mouse_mode !== RED.state.QUICK_JOINING && (evt.ctrlKey || evt.metaKey)) {
|
||||
mouse_mode = RED.state.QUICK_JOINING;
|
||||
document.body.style.cursor = "crosshair";
|
||||
showDragLines([{node:d,port:0,portType: PORT_TYPE_OUTPUT}]);
|
||||
$(window).on('keyup',disableQuickJoinEventHandler);
|
||||
} else if (event.button != 2) {
|
||||
nodeMouseDown.call(junction[0][0],d)
|
||||
// clearSelection();
|
||||
// movingSet.add(d);
|
||||
// mousedown_node = d;
|
||||
// mouse_mode = RED.state.MOVING;
|
||||
// var mouse = d3.touches(junction[0][0])[0]||d3.mouse(junction[0][0]);
|
||||
// mouse[0] += d.x-d.w/2;
|
||||
// mouse[1] += d.y-d.h/2;
|
||||
// prepareDrag(mouse);
|
||||
}
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
}
|
||||
|
||||
function prepareDrag(mouse) {
|
||||
mouse_mode = RED.state.MOVING;
|
||||
// Called when movingSet should be prepared to be dragged
|
||||
@@ -3313,8 +3447,6 @@ RED.view = (function() {
|
||||
)
|
||||
lastClickNode = mousedown_node;
|
||||
|
||||
var i;
|
||||
|
||||
if (!d.selected && d.g /*&& !RED.nodes.group(d.g).selected*/) {
|
||||
var nodeGroup = RED.nodes.group(d.g);
|
||||
|
||||
@@ -3587,6 +3719,11 @@ RED.view = (function() {
|
||||
function portMouseOverProxy(e) { portMouseOver(d3.select(this), this.__data__,this.__portType__,this.__portIndex__, e); }
|
||||
function portMouseOutProxy(e) { portMouseOut(d3.select(this), this.__data__,this.__portType__,this.__portIndex__, e); }
|
||||
|
||||
function junctionMouseOverProxy(e) { junctionMouseOver(d3.select(this), this.__data__) }
|
||||
function junctionMouseOutProxy(e) { junctionMouseOut(d3.select(this), this.__data__) }
|
||||
function junctionMouseDownProxy(e) { junctionMouseDown(d3.select(this), this.__data__, e) }
|
||||
function junctionMouseUpProxy(e) { junctionMouseUp(d3.select(this), this.__data__) }
|
||||
|
||||
function linkMouseDown(d) {
|
||||
if (mouse_mode === RED.state.SELECTING_NODE) {
|
||||
d3.event.stopPropagation();
|
||||
@@ -4721,6 +4858,62 @@ RED.view = (function() {
|
||||
})
|
||||
}
|
||||
|
||||
var junction = junctionLayer.selectAll(".red-ui-flow-junction").data(
|
||||
activeJunctions,
|
||||
d => d.id
|
||||
)
|
||||
var junctionEnter = junction.enter().insert("svg:g").attr("class","red-ui-flow-junction")
|
||||
junctionEnter.each(function(d,i) {
|
||||
var junction = d3.select(this);
|
||||
var contents = document.createDocumentFragment();
|
||||
// d.added = true;
|
||||
var junctionBack = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
||||
junctionBack.setAttribute("class","red-ui-flow-junction-background");
|
||||
junctionBack.setAttribute("x",-5);
|
||||
junctionBack.setAttribute("y",-5);
|
||||
junctionBack.setAttribute("width",10);
|
||||
junctionBack.setAttribute("height",10);
|
||||
junctionBack.setAttribute("rx",5);
|
||||
junctionBack.setAttribute("ry",5);
|
||||
junctionBack.__data__ = d;
|
||||
this.__junctionBack__ = junctionBack;
|
||||
contents.appendChild(junctionBack);
|
||||
|
||||
junctionBack.addEventListener("mouseover", junctionMouseOverProxy);
|
||||
junctionBack.addEventListener("mouseout", junctionMouseOutProxy);
|
||||
junctionBack.addEventListener("mouseup", portMouseUpProxy);
|
||||
junctionBack.addEventListener("mousedown", junctionMouseDownProxy);
|
||||
|
||||
// d3.select(junctionBack).on("mousedown", nodeMouseDown);
|
||||
|
||||
this.__portType__ = PORT_TYPE_INPUT
|
||||
this.__portIndex__ = 0
|
||||
// function portMouseUpProxy(e) { portMouseUp(this.__data__,this.__portType__,this.__portIndex__, e); }
|
||||
|
||||
junction[0][0].appendChild(contents);
|
||||
})
|
||||
junction.exit().remove();
|
||||
junction.each(function(d) {
|
||||
var junction = d3.select(this);
|
||||
this.setAttribute("transform", "translate(" + (d.x) + "," + (d.y) + ")");
|
||||
if (d.dirty) {
|
||||
junction.classed("selected", !!d.selected)
|
||||
dirtyNodes[d.id] = d;
|
||||
|
||||
if (d.g) {
|
||||
if (!dirtyGroups[d.g]) {
|
||||
var gg = d.g;
|
||||
while (gg && !dirtyGroups[gg]) {
|
||||
dirtyGroups[gg] = RED.nodes.group(gg);
|
||||
gg = dirtyGroups[gg].g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
var link = linkLayer.selectAll(".red-ui-flow-link").data(
|
||||
activeLinks,
|
||||
function(d) {
|
||||
@@ -4747,6 +4940,27 @@ RED.view = (function() {
|
||||
selectedLinks.add(d)
|
||||
l.classed("red-ui-flow-link-splice",true)
|
||||
redraw()
|
||||
} else if (mouse_mode === RED.state.SLICING_JUNCTION) {
|
||||
if (!l.classed("red-ui-flow-link-splice")) {
|
||||
// Find intersection point
|
||||
var lineLength = pathLine.getTotalLength();
|
||||
var pos;
|
||||
var delta = Infinity;
|
||||
for (var i = 0; i < lineLength; i++) {
|
||||
var linePos = pathLine.getPointAtLength(i);
|
||||
var posDeltaX = Math.abs(linePos.x-d3.event.offsetX)
|
||||
var posDeltaY = Math.abs(linePos.y-d3.event.offsetY)
|
||||
var posDelta = posDeltaX*posDeltaX + posDeltaY*posDeltaY
|
||||
if (posDelta < delta) {
|
||||
pos = linePos
|
||||
delta = posDelta
|
||||
}
|
||||
}
|
||||
d._sliceLocation = pos
|
||||
selectedLinks.add(d)
|
||||
l.classed("red-ui-flow-link-splice",true)
|
||||
redraw()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4773,9 +4987,9 @@ RED.view = (function() {
|
||||
var numOutputs = d.source.outputs || 1;
|
||||
var sourcePort = d.sourcePort || 0;
|
||||
var y = -((numOutputs-1)/2)*13 +13*sourcePort;
|
||||
d.x1 = d.source.x+d.source.w/2;
|
||||
d.x1 = d.source.x+(d.source.w/2||0);
|
||||
d.y1 = d.source.y+y;
|
||||
d.x2 = d.target.x-d.target.w/2;
|
||||
d.x2 = d.target.x-(d.target.w/2||0);
|
||||
d.y2 = d.target.y;
|
||||
|
||||
// return "M "+d.x1+" "+d.y1+
|
||||
@@ -5234,6 +5448,7 @@ RED.view = (function() {
|
||||
var new_nodes = result.nodes;
|
||||
var new_links = result.links;
|
||||
var new_groups = result.groups;
|
||||
var new_junctions = result.junctions;
|
||||
var new_workspaces = result.workspaces;
|
||||
var new_subflows = result.subflows;
|
||||
var removedNodes = result.removedNodes;
|
||||
@@ -5243,6 +5458,7 @@ RED.view = (function() {
|
||||
}
|
||||
var new_ms = new_nodes.filter(function(n) { return n.hasOwnProperty("x") && n.hasOwnProperty("y") && n.z == RED.workspaces.active() });
|
||||
new_ms = new_ms.concat(new_groups.filter(function(g) { return g.z === RED.workspaces.active()}))
|
||||
new_ms = new_ms.concat(new_junctions.filter(function(j) { return j.z === RED.workspaces.active()}))
|
||||
var new_node_ids = new_nodes.map(function(n){ n.changed = true; return n.id; });
|
||||
|
||||
clearSelection();
|
||||
@@ -5276,9 +5492,11 @@ RED.view = (function() {
|
||||
node.n.moved = true;
|
||||
node.n.x -= dx - mouse_position[0];
|
||||
node.n.y -= dy - mouse_position[1];
|
||||
node.n.w = node_width;
|
||||
node.n.h = node_height;
|
||||
node.n.resize = true;
|
||||
if (node.n.type !== 'junction') {
|
||||
node.n.w = node_width;
|
||||
node.n.h = node_height;
|
||||
node.n.resize = true;
|
||||
}
|
||||
node.dx = node.n.x - mouse_position[0];
|
||||
node.dy = node.n.y - mouse_position[1];
|
||||
if (node.n.type === "group") {
|
||||
@@ -5325,6 +5543,7 @@ RED.view = (function() {
|
||||
nodes:new_node_ids,
|
||||
links:new_links,
|
||||
groups:new_groups,
|
||||
junctions: new_junctions,
|
||||
workspaces:new_workspaces,
|
||||
subflows:new_subflows,
|
||||
dirty:RED.nodes.dirty()
|
||||
@@ -5372,6 +5591,7 @@ RED.view = (function() {
|
||||
}
|
||||
})
|
||||
var newGroupCount = new_groups.length;
|
||||
var newJunctionCount = new_junctions.length;
|
||||
if (new_workspaces.length > 0) {
|
||||
counts.push(RED._("clipboard.flow",{count:new_workspaces.length}));
|
||||
}
|
||||
@@ -5508,6 +5728,93 @@ RED.view = (function() {
|
||||
return selection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a node from a type string.
|
||||
* **NOTE:** Can throw on error - use `try` `catch` block when calling
|
||||
* @param {string} type The node type to create
|
||||
* @param {number} [x] (optional) The horizontal position on the workspace
|
||||
* @param {number} [y] (optional)The vertical on the workspace
|
||||
* @param {string} [z] (optional) The flow tab this node will belong to. Defaults to active workspace.
|
||||
* @returns An object containing the `node` and a `historyEvent`
|
||||
* @private
|
||||
*/
|
||||
function createNode(type, x, y, z) {
|
||||
var m = /^subflow:(.+)$/.exec(type);
|
||||
var activeSubflow = z ? RED.nodes.subflow(z) : null;
|
||||
if (activeSubflow && m) {
|
||||
var subflowId = m[1];
|
||||
if (subflowId === activeSubflow.id) {
|
||||
throw new Error(RED._("notification.error", { message: RED._("notification.errors.cannotAddSubflowToItself") }))
|
||||
}
|
||||
if (RED.nodes.subflowContains(m[1], activeSubflow.id)) {
|
||||
throw new Error(RED._("notification.error", { message: RED._("notification.errors.cannotAddCircularReference") }))
|
||||
}
|
||||
}
|
||||
|
||||
var nn = { id: RED.nodes.id(), z: z || RED.workspaces.active() };
|
||||
|
||||
nn.type = type;
|
||||
nn._def = RED.nodes.getType(nn.type);
|
||||
|
||||
if (!m) {
|
||||
nn.inputs = nn._def.inputs || 0;
|
||||
nn.outputs = nn._def.outputs;
|
||||
|
||||
for (var d in nn._def.defaults) {
|
||||
if (nn._def.defaults.hasOwnProperty(d)) {
|
||||
if (nn._def.defaults[d].value !== undefined) {
|
||||
nn[d] = JSON.parse(JSON.stringify(nn._def.defaults[d].value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nn._def.onadd) {
|
||||
try {
|
||||
nn._def.onadd.call(nn);
|
||||
} catch (err) {
|
||||
console.log("Definition error: " + nn.type + ".onadd:", err);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var subflow = RED.nodes.subflow(m[1]);
|
||||
nn.name = "";
|
||||
nn.inputs = subflow.in.length;
|
||||
nn.outputs = subflow.out.length;
|
||||
}
|
||||
|
||||
nn.changed = true;
|
||||
nn.moved = true;
|
||||
|
||||
nn.w = RED.view.node_width;
|
||||
nn.h = Math.max(RED.view.node_height, (nn.outputs || 0) * 15);
|
||||
nn.resize = true;
|
||||
if (x != null && typeof x == "number" && x >= 0) {
|
||||
nn.x = x;
|
||||
}
|
||||
if (y != null && typeof y == "number" && y >= 0) {
|
||||
nn.y = y;
|
||||
}
|
||||
var historyEvent = {
|
||||
t: "add",
|
||||
nodes: [nn.id],
|
||||
dirty: RED.nodes.dirty()
|
||||
}
|
||||
if (activeSubflow) {
|
||||
var subflowRefresh = RED.subflow.refresh(true);
|
||||
if (subflowRefresh) {
|
||||
historyEvent.subflow = {
|
||||
id: activeSubflow.id,
|
||||
changed: activeSubflow.changed,
|
||||
instances: subflowRefresh.instances
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
node: nn,
|
||||
historyEvent: historyEvent
|
||||
}
|
||||
}
|
||||
|
||||
function calculateNodeDimensions(node) {
|
||||
var result = [node_width,node_height];
|
||||
try {
|
||||
@@ -5531,6 +5838,37 @@ RED.view = (function() {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function flashNode(n) {
|
||||
let node = n;
|
||||
if(typeof node === "string") { node = RED.nodes.node(n); }
|
||||
if(!node) { return; }
|
||||
|
||||
const flashingNode = flashingNodeTimer && flashingNodeId && RED.nodes.node(flashingNodeId);
|
||||
if(flashingNode) {
|
||||
//cancel current flashing node before flashing new node
|
||||
clearInterval(flashingNodeTimer);
|
||||
flashingNodeTimer = null;
|
||||
flashingNode.dirty = true;
|
||||
flashingNode.highlighted = false;
|
||||
}
|
||||
|
||||
flashingNodeTimer = setInterval(function(flashEndTime) {
|
||||
node.dirty = true;
|
||||
if (flashEndTime >= Date.now()) {
|
||||
node.highlighted = !node.highlighted;
|
||||
} else {
|
||||
clearInterval(flashingNodeTimer);
|
||||
flashingNodeTimer = null;
|
||||
node.highlighted = false;
|
||||
flashingNodeId = null;
|
||||
}
|
||||
RED.view.redraw();
|
||||
}, 100, Date.now() + 2200)
|
||||
flashingNodeId = node.id;
|
||||
node.highlighted = true;
|
||||
RED.view.redraw();
|
||||
}
|
||||
return {
|
||||
init: init,
|
||||
state:function(state) {
|
||||
@@ -5591,7 +5929,21 @@ RED.view = (function() {
|
||||
redraw(true);
|
||||
},
|
||||
selection: getSelection,
|
||||
|
||||
clearSelection: clearSelection,
|
||||
createNode: createNode,
|
||||
/** default node width */
|
||||
get node_width() {
|
||||
return node_width;
|
||||
},
|
||||
/** default node height */
|
||||
get node_height() {
|
||||
return node_height;
|
||||
},
|
||||
/** snap to grid option state */
|
||||
get snapGrid() {
|
||||
return snapGrid;
|
||||
},
|
||||
/** gets the current scale factor */
|
||||
scale: function() {
|
||||
return scaleFactor;
|
||||
},
|
||||
@@ -5613,7 +5965,7 @@ RED.view = (function() {
|
||||
getActiveGroup: function() { return activeGroup },
|
||||
reveal: function(id,triggerHighlight) {
|
||||
if (RED.nodes.workspace(id) || RED.nodes.subflow(id)) {
|
||||
RED.workspaces.show(id);
|
||||
RED.workspaces.show(id, null, null, true);
|
||||
} else {
|
||||
var node = RED.nodes.node(id) || RED.nodes.group(id);
|
||||
if (node) {
|
||||
@@ -5638,24 +5990,7 @@ RED.view = (function() {
|
||||
},200);
|
||||
}
|
||||
if (triggerHighlight !== false) {
|
||||
node.highlighted = true;
|
||||
if (!node._flashing) {
|
||||
node._flashing = true;
|
||||
var flash = 22;
|
||||
var flashFunc = function() {
|
||||
flash--;
|
||||
node.dirty = true;
|
||||
if (flash >= 0) {
|
||||
node.highlighted = !node.highlighted;
|
||||
setTimeout(flashFunc,100);
|
||||
} else {
|
||||
node.highlighted = false;
|
||||
delete node._flashing;
|
||||
}
|
||||
RED.view.redraw();
|
||||
}
|
||||
flashFunc();
|
||||
}
|
||||
flashNode(node);
|
||||
}
|
||||
} else if (node._def.category === 'config') {
|
||||
RED.sidebar.config.show(id);
|
||||
|
||||
@@ -24,6 +24,9 @@ RED.workspaces = (function() {
|
||||
var hideStack = [];
|
||||
var viewStackPos = 0;
|
||||
|
||||
let flashingTab;
|
||||
let flashingTabTimer;
|
||||
|
||||
function addToViewStack(id) {
|
||||
if (viewStackPos !== viewStack.length) {
|
||||
viewStack.splice(viewStackPos);
|
||||
@@ -428,6 +431,9 @@ RED.workspaces = (function() {
|
||||
}
|
||||
}
|
||||
})
|
||||
RED.actions.add("core:list-modified-nodes",function() {
|
||||
RED.actions.invoke("core:search","is:modified ");
|
||||
})
|
||||
RED.actions.add("core:list-hidden-flows",function() {
|
||||
RED.actions.invoke("core:search","is:hidden ");
|
||||
})
|
||||
@@ -528,6 +534,31 @@ RED.workspaces = (function() {
|
||||
workspace_tabs.order(order);
|
||||
}
|
||||
|
||||
function flashTab(tabId) {
|
||||
if(flashingTab && flashingTab.length) {
|
||||
//cancel current flashing node before flashing new node
|
||||
clearInterval(flashingTabTimer);
|
||||
flashingTabTimer = null;
|
||||
flashingTab.removeClass('highlighted');
|
||||
flashingTab = null;
|
||||
}
|
||||
let tab = $("#red-ui-tab-" + tabId);
|
||||
if(!tab || !tab.length) { return; }
|
||||
|
||||
flashingTabTimer = setInterval(function(flashEndTime) {
|
||||
if (flashEndTime >= Date.now()) {
|
||||
const highlighted = tab.hasClass("highlighted");
|
||||
tab.toggleClass('highlighted', !highlighted)
|
||||
} else {
|
||||
clearInterval(flashingTabTimer);
|
||||
flashingTabTimer = null;
|
||||
flashingTab = null;
|
||||
tab.removeClass('highlighted');
|
||||
}
|
||||
}, 100, Date.now() + 2200);
|
||||
flashingTab = tab;
|
||||
tab.addClass('highlighted');
|
||||
}
|
||||
return {
|
||||
init: init,
|
||||
add: addWorkspace,
|
||||
@@ -560,7 +591,7 @@ RED.workspaces = (function() {
|
||||
isHidden: function(id) {
|
||||
return hideStack.includes(id)
|
||||
},
|
||||
show: function(id,skipStack,unhideOnly) {
|
||||
show: function(id,skipStack,unhideOnly,flash) {
|
||||
if (!workspace_tabs.contains(id)) {
|
||||
var sf = RED.nodes.subflow(id);
|
||||
if (sf) {
|
||||
@@ -582,6 +613,9 @@ RED.workspaces = (function() {
|
||||
}
|
||||
workspace_tabs.activateTab(id);
|
||||
}
|
||||
if(flash) {
|
||||
flashTab(id.replace(".","-"))
|
||||
}
|
||||
},
|
||||
refresh: function() {
|
||||
RED.nodes.eachWorkspace(function(ws) {
|
||||
|
||||
@@ -379,3 +379,17 @@ g.red-ui-flow-link-unknown path.red-ui-flow-link-line {
|
||||
white-space: pre;
|
||||
@include disable-selection;
|
||||
}
|
||||
.red-ui-flow-junction-background {
|
||||
stroke: $node-border;
|
||||
stroke-width: 1;
|
||||
fill: $node-port-background;
|
||||
cursor: crosshair;
|
||||
}
|
||||
.red-ui-flow-junction-hovered {
|
||||
stroke: $port-selected-color;
|
||||
fill: $port-selected-color;
|
||||
}
|
||||
.red-ui-flow-junction.selected .red-ui-flow-junction-background {
|
||||
stroke: $port-selected-color;
|
||||
// fill: $port-selected-color;
|
||||
}
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
.red-ui-search-result-node {
|
||||
&.red-ui-palette-icon-flow,
|
||||
&.red-ui-palette-icon-group,
|
||||
&.red-ui-palette-icon-junction,
|
||||
&.red-ui-palette-icon-selection {
|
||||
background: none;
|
||||
border-color: transparent;
|
||||
@@ -268,6 +269,7 @@
|
||||
|
||||
&.red-ui-palette-icon-flow,
|
||||
&.red-ui-palette-icon-group,
|
||||
&.red-ui-palette-icon-junction,
|
||||
&.red-ui-palette-icon-selection {
|
||||
background: none;
|
||||
border-color: transparent;
|
||||
@@ -303,6 +305,7 @@
|
||||
&.red-ui-palette-icon-flow {
|
||||
margin-top: -2px;
|
||||
}
|
||||
&.red-ui-palette-icon-junction .red-ui-palette-icon-fa,
|
||||
&.red-ui-palette-icon-group .red-ui-palette-icon-fa {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -66,8 +66,9 @@
|
||||
border-left-width: 3px;
|
||||
border-right-width: 3px;
|
||||
.red-ui-palette-icon-fa {
|
||||
font-size: 11px;
|
||||
position: relative;
|
||||
top: -2.5px;
|
||||
top: -3px;
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ ul.red-ui-sidebar-node-config-list {
|
||||
border-color: transparent;
|
||||
box-shadow: 0 0 0 2px $node-selected-color;
|
||||
}
|
||||
&.highlighted {
|
||||
border-color: transparent;
|
||||
outline: dashed $node-selected-color 4px;
|
||||
}
|
||||
}
|
||||
.red-ui-palette-label {
|
||||
margin-left: 8px;
|
||||
|
||||
@@ -85,6 +85,10 @@
|
||||
&:not(.active) a:hover+a.red-ui-tab-close {
|
||||
background: $tab-background-hover;
|
||||
}
|
||||
&.highlighted {
|
||||
box-shadow: 0px 0px 4px 2px $node-selected-color;
|
||||
border: dashed 1px $node-selected-color;
|
||||
}
|
||||
&.active {
|
||||
background: $tab-background-active;
|
||||
font-weight: bold;
|
||||
|
||||
@@ -135,6 +135,13 @@
|
||||
margin-top: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-counter {
|
||||
display: inline-block;
|
||||
font-size: smaller;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
a.red-ui-footer-button,
|
||||
|
||||
6
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/css/all.min.css
vendored
Normal file
6
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/css/all.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
* Copyright 2022 Fonticons, Inc.
|
||||
*/
|
||||
@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f250,u+f252,u+f27a}
|
||||
6
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/css/v4-shims.min.css
vendored
Normal file
6
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/css/v4-shims.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-brands-400.ttf
vendored
Normal file
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-brands-400.ttf
vendored
Normal file
Binary file not shown.
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-brands-400.woff2
vendored
Normal file
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-brands-400.woff2
vendored
Normal file
Binary file not shown.
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-regular-400.ttf
vendored
Normal file
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-regular-400.ttf
vendored
Normal file
Binary file not shown.
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-regular-400.woff2
vendored
Normal file
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-regular-400.woff2
vendored
Normal file
Binary file not shown.
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-solid-900.ttf
vendored
Normal file
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-solid-900.ttf
vendored
Normal file
Binary file not shown.
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-solid-900.woff2
vendored
Normal file
BIN
packages/node_modules/@node-red/editor-client/src/vendor/font-awesome/webfonts/fa-solid-900.woff2
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -25,7 +25,8 @@
|
||||
<link rel="icon" type="image/png" href="{{ page.favicon }}">
|
||||
<link rel="mask-icon" href="{{ page.tabicon.icon }}" color="{{ page.tabicon.colour }}">
|
||||
<link rel="stylesheet" href="vendor/jquery/css/base/jquery-ui.min.css?v={{ page.version }}">
|
||||
<link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css?v={{ page.version }}">
|
||||
<link rel="stylesheet" href="vendor/font-awesome/css/all.min.css?v={{ page.version }}">
|
||||
<link rel="stylesheet" href="vendor/font-awesome/css/v4-shims.min.css?v={{ page.version }}">
|
||||
<link rel="stylesheet" href="red/style.min.css?v={{ page.version }}">
|
||||
{{#page.css}}
|
||||
<link rel="stylesheet" href="{{.}}">
|
||||
|
||||
5
packages/node_modules/@node-red/nodes/core/common/05-junction.html
vendored
Normal file
5
packages/node_modules/@node-red/nodes/core/common/05-junction.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<!--
|
||||
05-junction.html
|
||||
This file exists so that the runtime loads the Junction node into the registry,
|
||||
but it is empty so it doesn't appear in the editor palette
|
||||
-->
|
||||
12
packages/node_modules/@node-red/nodes/core/common/05-junction.js
vendored
Normal file
12
packages/node_modules/@node-red/nodes/core/common/05-junction.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
function JunctionNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.on("input",function(msg, send, done) {
|
||||
send(msg);
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("junction",JunctionNode);
|
||||
}
|
||||
@@ -507,6 +507,9 @@
|
||||
$("#node-input-complete").val($("#node-input-typed-complete").typedInput('value'));
|
||||
}
|
||||
$("#node-input-statusVal").val($("#node-input-typed-status").typedInput('value'));
|
||||
},
|
||||
onadd: function() {
|
||||
RED.actions.invoke("core:generate-node-names",this)
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -209,6 +209,8 @@
|
||||
}
|
||||
|
||||
function onAdd() {
|
||||
RED.actions.invoke("core:generate-node-names",this)
|
||||
|
||||
for (var i=0;i<this.links.length;i++) {
|
||||
var n = RED.nodes.node(this.links[i]);
|
||||
if (n && n.links.indexOf(this.id) === -1) {
|
||||
@@ -286,7 +288,10 @@
|
||||
oneditsave: function() {
|
||||
onEditSave(this);
|
||||
},
|
||||
oneditresize: resizeNodeList
|
||||
oneditresize: resizeNodeList,
|
||||
onadd: function() {
|
||||
RED.actions.invoke("core:generate-node-names",this)
|
||||
}
|
||||
});
|
||||
|
||||
RED.nodes.registerType('link out',{
|
||||
|
||||
@@ -55,6 +55,7 @@ module.exports = function(RED) {
|
||||
catch(e) { return false;}
|
||||
}
|
||||
else if (b === "null") { return a === null; }
|
||||
else if (b === "number") { return typeof a === b && !isNaN(a) }
|
||||
else { return typeof a === b && !Array.isArray(a) && !Buffer.isBuffer(a) && a !== null; }
|
||||
},
|
||||
'head': function(a, b, c, d, parts) {
|
||||
|
||||
@@ -310,6 +310,12 @@ describe('switch Node', function() {
|
||||
it('should check if payload if of type number 0', function(done) {
|
||||
genericSwitchTest("istype", "number", true, true, 0, done);
|
||||
});
|
||||
it('should check if payload if of type number NaN', function(done) {
|
||||
genericSwitchTest("istype", "number", true, false, parseInt("banana"), done);
|
||||
});
|
||||
it('should check if payload if of type number Infinity', function(done) {
|
||||
genericSwitchTest("istype", "number", true, true, 1/0, done);
|
||||
});
|
||||
it('should check if payload if of type boolean true', function(done) {
|
||||
genericSwitchTest("istype", "boolean", true, true, true, done);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user