mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge branch 'dev' into function-modules
This commit is contained in:
@@ -72,9 +72,7 @@ RED.clipboard = (function() {
|
||||
text: RED._("clipboard.export.copy"),
|
||||
click: function() {
|
||||
if (activeTab === "red-ui-clipboard-dialog-export-tab-clipboard") {
|
||||
$("#red-ui-clipboard-dialog-export-text").select();
|
||||
document.execCommand("copy");
|
||||
document.getSelection().removeAllRanges();
|
||||
copyText($("#red-ui-clipboard-dialog-export-text").val());
|
||||
RED.notify(RED._("clipboard.nodesExported"),{id:"clipboard"});
|
||||
$( this ).dialog( "close" );
|
||||
} else {
|
||||
@@ -222,14 +220,22 @@ RED.clipboard = (function() {
|
||||
'</div>'+
|
||||
'<div id="red-ui-clipboard-dialog-export-tabs-content" class="red-ui-clipboard-dialog-tabs-content">'+
|
||||
'<div id="red-ui-clipboard-dialog-export-tab-clipboard" class="red-ui-clipboard-dialog-tab-clipboard">'+
|
||||
'<div class="form-row" style="height:calc(100% - 30px)">'+
|
||||
'<textarea readonly id="red-ui-clipboard-dialog-export-text"></textarea>'+
|
||||
'<div id="red-ui-clipboard-dialog-export-tab-clipboard-tab-bar">'+
|
||||
'<ul id="red-ui-clipboard-dialog-export-tab-clipboard-tabs"></ul>'+
|
||||
'</div>'+
|
||||
'<div class="form-row" style="text-align: right;">'+
|
||||
'<span id="red-ui-clipboard-dialog-export-fmt-group" class="button-group">'+
|
||||
'<a id="red-ui-clipboard-dialog-export-fmt-mini" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.compact"></a>'+
|
||||
'<a id="red-ui-clipboard-dialog-export-fmt-full" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.formatted"></a>'+
|
||||
'</span>'+
|
||||
'<div class="red-ui-clipboard-dialog-export-tab-clipboard-tab" id="red-ui-clipboard-dialog-export-tab-clipboard-preview">'+
|
||||
'<div id="red-ui-clipboard-dialog-export-tab-clipboard-preview-list"></div>'+
|
||||
'</div>'+
|
||||
'<div class="red-ui-clipboard-dialog-export-tab-clipboard-tab" id="red-ui-clipboard-dialog-export-tab-clipboard-json">'+
|
||||
'<div class="form-row" style="height:calc(100% - 40px)">'+
|
||||
'<textarea readonly id="red-ui-clipboard-dialog-export-text"></textarea>'+
|
||||
'</div>'+
|
||||
'<div class="form-row" style="text-align: right;">'+
|
||||
'<span id="red-ui-clipboard-dialog-export-fmt-group" class="button-group">'+
|
||||
'<a id="red-ui-clipboard-dialog-export-fmt-mini" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.compact"></a>'+
|
||||
'<a id="red-ui-clipboard-dialog-export-fmt-full" class="red-ui-button red-ui-button-small toggle" href="#" data-i18n="clipboard.export.formatted"></a>'+
|
||||
'</span>'+
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'<div id="red-ui-clipboard-dialog-export-tab-library" class="red-ui-clipboard-dialog-tab-library">'+
|
||||
@@ -592,6 +598,30 @@ RED.clipboard = (function() {
|
||||
})
|
||||
loadFlowLibrary(libraryBrowser,"local",RED._("library.types.local"));
|
||||
|
||||
var clipboardTabs = RED.tabs.create({
|
||||
id: "red-ui-clipboard-dialog-export-tab-clipboard-tabs",
|
||||
onchange: function(tab) {
|
||||
$(".red-ui-clipboard-dialog-export-tab-clipboard-tab").hide();
|
||||
$("#" + tab.id).show();
|
||||
}
|
||||
});
|
||||
|
||||
clipboardTabs.addTab({
|
||||
id: "red-ui-clipboard-dialog-export-tab-clipboard-preview",
|
||||
label: RED._("clipboard.exportNodes")
|
||||
});
|
||||
|
||||
clipboardTabs.addTab({
|
||||
id: "red-ui-clipboard-dialog-export-tab-clipboard-json",
|
||||
label: RED._("editor.types.json")
|
||||
});
|
||||
|
||||
|
||||
var previewList = $("#red-ui-clipboard-dialog-export-tab-clipboard-preview-list").css({position:"absolute",top:0,right:0,bottom:0,left:0}).treeList({
|
||||
data: []
|
||||
})
|
||||
refreshExportPreview();
|
||||
|
||||
$("#red-ui-clipboard-dialog-tab-library-name").val("flows.json").select();
|
||||
|
||||
dialogContainer.i18n();
|
||||
@@ -630,10 +660,10 @@ RED.clipboard = (function() {
|
||||
}
|
||||
$(this).parent().children().removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
var type = $(this).attr('id');
|
||||
var type = $(this).attr('id').substring("red-ui-clipboard-dialog-export-rng-".length);
|
||||
var flow = "";
|
||||
var nodes = null;
|
||||
if (type === 'red-ui-clipboard-dialog-export-rng-selected') {
|
||||
if (type === 'selected') {
|
||||
var selection = RED.workspaces.selection();
|
||||
if (selection.length > 0) {
|
||||
nodes = [];
|
||||
@@ -647,14 +677,14 @@ RED.clipboard = (function() {
|
||||
}
|
||||
// Don't include the subflow meta-port nodes in the exported selection
|
||||
nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'}));
|
||||
} else if (type === 'red-ui-clipboard-dialog-export-rng-flow') {
|
||||
} else if (type === 'flow') {
|
||||
var activeWorkspace = RED.workspaces.active();
|
||||
nodes = RED.nodes.groups(activeWorkspace);
|
||||
nodes = nodes.concat(RED.nodes.filterNodes({z:activeWorkspace}));
|
||||
var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace);
|
||||
nodes.unshift(parentNode);
|
||||
nodes = RED.nodes.createExportableNodeSet(nodes);
|
||||
} else if (type === 'red-ui-clipboard-dialog-export-rng-full') {
|
||||
} else if (type === 'full') {
|
||||
nodes = RED.nodes.createCompleteNodeSet(false);
|
||||
}
|
||||
if (nodes !== null) {
|
||||
@@ -670,8 +700,10 @@ RED.clipboard = (function() {
|
||||
$("#red-ui-clipboard-dialog-export").addClass('disabled');
|
||||
}
|
||||
$("#red-ui-clipboard-dialog-export-text").val(flow);
|
||||
setTimeout(function() { $("#red-ui-clipboard-dialog-export-text").scrollTop(0); },50);
|
||||
$("#red-ui-clipboard-dialog-export-text").trigger("focus");
|
||||
setTimeout(function() {
|
||||
$("#red-ui-clipboard-dialog-export-text").scrollTop(0);
|
||||
refreshExportPreview(type);
|
||||
},50);
|
||||
})
|
||||
|
||||
$("#red-ui-clipboard-dialog-ok").hide();
|
||||
@@ -717,6 +749,93 @@ RED.clipboard = (function() {
|
||||
|
||||
}
|
||||
|
||||
function refreshExportPreview(type) {
|
||||
|
||||
var flowData = $("#red-ui-clipboard-dialog-export-text").val() || "[]";
|
||||
var flow = JSON.parse(flowData);
|
||||
var flows = {};
|
||||
var subflows = {};
|
||||
var nodes = [];
|
||||
var nodesByZ = {};
|
||||
|
||||
var treeFlows = [];
|
||||
var treeSubflows = [];
|
||||
|
||||
flow.forEach(function(node) {
|
||||
if (node.type === "tab") {
|
||||
flows[node.id] = {
|
||||
element: getFlowLabel(node,false),
|
||||
deferBuild: type !== "flow",
|
||||
expanded: type === "flow",
|
||||
children: []
|
||||
};
|
||||
treeFlows.push(flows[node.id])
|
||||
} else if (node.type === "subflow") {
|
||||
subflows[node.id] = {
|
||||
element: getNodeLabel(node,false),
|
||||
deferBuild: true,
|
||||
children: []
|
||||
};
|
||||
treeSubflows.push(subflows[node.id])
|
||||
} else {
|
||||
nodes.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
var globalNodes = [];
|
||||
var parentlessNodes = [];
|
||||
|
||||
nodes.forEach(function(node) {
|
||||
var treeNode = {
|
||||
element: getNodeLabel(node, false, false)
|
||||
};
|
||||
if (node.z) {
|
||||
if (!flows[node.z] && !subflows[node.z]) {
|
||||
parentlessNodes.push(treeNode)
|
||||
} else if (flows[node.z]) {
|
||||
flows[node.z].children.push(treeNode)
|
||||
} else if (subflows[node.z]) {
|
||||
subflows[node.z].children.push(treeNode)
|
||||
}
|
||||
} else {
|
||||
globalNodes.push(treeNode);
|
||||
}
|
||||
});
|
||||
var treeData = [];
|
||||
|
||||
if (parentlessNodes.length > 0) {
|
||||
treeData = treeData.concat(parentlessNodes);
|
||||
}
|
||||
if (type === "flow") {
|
||||
treeData = treeData.concat(treeFlows);
|
||||
} else if (treeFlows.length > 0) {
|
||||
treeData.push({
|
||||
label: RED._("menu.label.flows"),
|
||||
deferBuild: treeFlows.length > 20,
|
||||
expanded: treeFlows.length <= 20,
|
||||
children: treeFlows
|
||||
})
|
||||
}
|
||||
if (treeSubflows.length > 0) {
|
||||
treeData.push({
|
||||
label: RED._("menu.label.subflows"),
|
||||
deferBuild: treeSubflows.length > 10,
|
||||
expanded: treeSubflows.length <= 10,
|
||||
children: treeSubflows
|
||||
})
|
||||
}
|
||||
if (globalNodes.length > 0) {
|
||||
treeData.push({
|
||||
label: RED._("sidebar.info.globalConfig"),
|
||||
deferBuild: globalNodes.length > 10,
|
||||
expanded: globalNodes.length <= 10,
|
||||
children: globalNodes
|
||||
})
|
||||
}
|
||||
|
||||
$("#red-ui-clipboard-dialog-export-tab-clipboard-preview-list").treeList('data',treeData);
|
||||
}
|
||||
|
||||
function loadFlowLibrary(browser,library,label) {
|
||||
// if (includeExamples) {
|
||||
// listing.push({
|
||||
@@ -756,6 +875,7 @@ RED.clipboard = (function() {
|
||||
}
|
||||
function copyText(value,element,msg) {
|
||||
var truncated = false;
|
||||
var currentFocus = document.activeElement;
|
||||
if (typeof value !== "string" ) {
|
||||
value = JSON.stringify(value, function(key,value) {
|
||||
if (value !== null && typeof value === 'object') {
|
||||
@@ -787,7 +907,7 @@ RED.clipboard = (function() {
|
||||
if (truncated) {
|
||||
msg += "_truncated";
|
||||
}
|
||||
$("#red-ui-clipboard-hidden").val(value).select();
|
||||
$("#red-ui-clipboard-hidden").val(value).focus().select();
|
||||
var result = document.execCommand("copy");
|
||||
if (result && element) {
|
||||
var popover = RED.popover.create({
|
||||
@@ -801,6 +921,10 @@ RED.clipboard = (function() {
|
||||
},1000);
|
||||
popover.open();
|
||||
}
|
||||
$("#red-ui-clipboard-hidden").val("");
|
||||
if (currentFocus) {
|
||||
$(currentFocus).focus();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -444,16 +444,18 @@ RED.editor = (function() {
|
||||
for (var d in definition.defaults) {
|
||||
if (definition.defaults.hasOwnProperty(d)) {
|
||||
if (definition.defaults[d].type) {
|
||||
var configTypeDef = RED.nodes.getType(definition.defaults[d].type);
|
||||
if (configTypeDef) {
|
||||
if (configTypeDef.exclusive) {
|
||||
prepareConfigNodeButton(node,d,definition.defaults[d].type,prefix);
|
||||
if (!definition.defaults[d]._type.array) {
|
||||
var configTypeDef = RED.nodes.getType(definition.defaults[d].type);
|
||||
if (configTypeDef && configTypeDef.category === 'config') {
|
||||
if (configTypeDef.exclusive) {
|
||||
prepareConfigNodeButton(node,d,definition.defaults[d].type,prefix);
|
||||
} else {
|
||||
prepareConfigNodeSelect(node,d,definition.defaults[d].type,prefix);
|
||||
}
|
||||
} else {
|
||||
prepareConfigNodeSelect(node,d,definition.defaults[d].type,prefix);
|
||||
console.log("Unknown type:", definition.defaults[d].type);
|
||||
preparePropertyEditor(node,d,prefix,definition.defaults);
|
||||
}
|
||||
} else {
|
||||
console.log("Unknown type:", definition.defaults[d].type);
|
||||
preparePropertyEditor(node,d,prefix,definition.defaults);
|
||||
}
|
||||
} else {
|
||||
preparePropertyEditor(node,d,prefix,definition.defaults);
|
||||
@@ -494,11 +496,13 @@ RED.editor = (function() {
|
||||
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
||||
completePrepare();
|
||||
} else {
|
||||
$.getJSON(getCredentialsURL(node.type, node.id), function (data) {
|
||||
node.credentials = data;
|
||||
node.credentials._ = $.extend(true,{},data);
|
||||
if (!/^subflow:/.test(definition.type)) {
|
||||
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
||||
getNodeCredentials(node.type, node.id, function(data) {
|
||||
if (data) {
|
||||
node.credentials = data;
|
||||
node.credentials._ = $.extend(true,{},data);
|
||||
if (!/^subflow:/.test(definition.type)) {
|
||||
populateCredentialsInputs(node, definition.credentials, node.credentials, prefix);
|
||||
}
|
||||
}
|
||||
completePrepare();
|
||||
});
|
||||
@@ -1086,8 +1090,11 @@ RED.editor = (function() {
|
||||
node.infoEditor = nodeInfoEditor;
|
||||
return nodeInfoEditor;
|
||||
}
|
||||
var buildingEditDialog = false;
|
||||
|
||||
function showEditDialog(node, defaultTab) {
|
||||
if (buildingEditDialog) { return }
|
||||
buildingEditDialog = true;
|
||||
var editing_node = node;
|
||||
var isDefaultIcon;
|
||||
var defaultIcon;
|
||||
@@ -1612,6 +1619,7 @@ RED.editor = (function() {
|
||||
if (defaultTab) {
|
||||
editorTabs.activateTab(defaultTab);
|
||||
}
|
||||
buildingEditDialog = false;
|
||||
done();
|
||||
});
|
||||
},
|
||||
@@ -1663,6 +1671,8 @@ RED.editor = (function() {
|
||||
* prefix - the input prefix of the parent property
|
||||
*/
|
||||
function showEditConfigNodeDialog(name,type,id,prefix) {
|
||||
if (buildingEditDialog) { return }
|
||||
buildingEditDialog = true;
|
||||
var adding = (id == "_ADD_");
|
||||
var node_def = RED.nodes.getType(type);
|
||||
var editing_config_node = RED.nodes.node(id);
|
||||
@@ -1826,6 +1836,7 @@ RED.editor = (function() {
|
||||
trayBody.i18n();
|
||||
trayFooter.i18n();
|
||||
finishedBuilding = true;
|
||||
buildingEditDialog = false;
|
||||
done();
|
||||
});
|
||||
},
|
||||
@@ -2149,6 +2160,8 @@ RED.editor = (function() {
|
||||
}
|
||||
|
||||
function showEditSubflowDialog(subflow) {
|
||||
if (buildingEditDialog) { return }
|
||||
buildingEditDialog = true;
|
||||
var editing_node = subflow;
|
||||
editStack.push(subflow);
|
||||
RED.view.state(RED.state.EDITING);
|
||||
@@ -2405,15 +2418,17 @@ RED.editor = (function() {
|
||||
|
||||
buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template", undefined, editing_node);
|
||||
trayBody.i18n();
|
||||
|
||||
$.getJSON(getCredentialsURL("subflow", subflow.id), function (data) {
|
||||
subflow.credentials = data;
|
||||
subflow.credentials._ = $.extend(true,{},data);
|
||||
|
||||
getNodeCredentials("subflow", subflow.id, function(data) {
|
||||
if (data) {
|
||||
subflow.credentials = data;
|
||||
subflow.credentials._ = $.extend(true,{},data);
|
||||
}
|
||||
$("#subflow-input-name").val(subflow.name);
|
||||
RED.text.bidi.prepareInput($("#subflow-input-name"));
|
||||
|
||||
finishedBuilding = true;
|
||||
buildingEditDialog = false;
|
||||
|
||||
done();
|
||||
});
|
||||
},
|
||||
@@ -2434,7 +2449,39 @@ RED.editor = (function() {
|
||||
RED.tray.show(trayOptions);
|
||||
}
|
||||
|
||||
function getNodeCredentials(type, id, done) {
|
||||
var timeoutNotification;
|
||||
var intialTimeout = setTimeout(function() {
|
||||
timeoutNotification = RED.notify($('<p data-i18n="[prepend]editor.loadCredentials"> <img src="red/images/spin.svg"/></p>').i18n(),{fixed: true})
|
||||
},800);
|
||||
|
||||
$.ajax({
|
||||
url: getCredentialsURL(type,id),
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
if (timeoutNotification) {
|
||||
timeoutNotification.close();
|
||||
timeoutNotification = null;
|
||||
}
|
||||
clearTimeout(intialTimeout);
|
||||
done(data);
|
||||
},
|
||||
error: function(jqXHR,status,error) {
|
||||
if (timeoutNotification) {
|
||||
timeoutNotification.close();
|
||||
timeoutNotification = null;
|
||||
}
|
||||
clearTimeout(intialTimeout);
|
||||
RED.notify(RED._("editor.errors.credentialLoadFailed"),"error")
|
||||
done(null);
|
||||
},
|
||||
timeout: 30000,
|
||||
});
|
||||
}
|
||||
|
||||
function showEditGroupDialog(group) {
|
||||
if (buildingEditDialog) { return }
|
||||
buildingEditDialog = true;
|
||||
var editing_node = group;
|
||||
editStack.push(group);
|
||||
RED.view.state(RED.state.EDITING);
|
||||
@@ -2658,6 +2705,7 @@ RED.editor = (function() {
|
||||
prepareEditDialog(group,group._def,"node-input", function() {
|
||||
trayBody.i18n();
|
||||
finishedBuilding = true;
|
||||
buildingEditDialog = false;
|
||||
done();
|
||||
});
|
||||
},
|
||||
|
@@ -97,13 +97,18 @@ RED.palette = (function() {
|
||||
label = RED.utils.sanitize(label);
|
||||
|
||||
|
||||
var words = label.split(/[ -]/);
|
||||
var words = label.split(/([ -]|\\n )/);
|
||||
|
||||
var displayLines = [];
|
||||
|
||||
var currentLine = "";
|
||||
for (var i=0;i<words.length;i++) {
|
||||
var word = words[i];
|
||||
if (word === "\\n ") {
|
||||
displayLines.push(currentLine);
|
||||
currentLine = "";
|
||||
continue;
|
||||
}
|
||||
var sep = (i == 0) ? "" : " ";
|
||||
var newWidth = RED.view.calculateTextWidth(currentLine+sep+word, "red-ui-palette-label");
|
||||
if (newWidth < nodeWidth) {
|
||||
@@ -165,7 +170,16 @@ RED.palette = (function() {
|
||||
metaData = typeInfo.set.module+" : ";
|
||||
}
|
||||
metaData += type;
|
||||
$('<button type="button" onclick="RED.sidebar.help.show(\''+type+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right"><i class="fa fa-book"></i></button>').appendTo(popOverContent)
|
||||
|
||||
if (/^subflow:/.test(type)) {
|
||||
$('<button type="button" onclick="RED.workspaces.show(\''+type.substring(8).replace(/'/g,"\\'")+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-pencil"></i></button>').appendTo(popOverContent)
|
||||
}
|
||||
|
||||
var safeType = type.replace(/'/g,"\\'");
|
||||
|
||||
$('<button type="button" onclick="RED.search.show(\'type:'+safeType+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-search"></i></button>').appendTo(popOverContent)
|
||||
$('<button type="button" onclick="RED.sidebar.help.show(\''+safeType+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-book"></i></button>').appendTo(popOverContent)
|
||||
|
||||
$('<p>',{style:"font-size: 0.8em"}).text(metaData).appendTo(popOverContent);
|
||||
}
|
||||
} catch(err) {
|
||||
@@ -396,7 +410,8 @@ RED.palette = (function() {
|
||||
RED.workspaces.show(nt.substring(8));
|
||||
e.preventDefault();
|
||||
});
|
||||
nodeInfo = RED.utils.renderMarkdown(def.info||"");
|
||||
var subflow = RED.nodes.subflow(nt.substring(8));
|
||||
nodeInfo = RED.utils.renderMarkdown(subflow.info||"");
|
||||
}
|
||||
setLabel(nt,d,label,nodeInfo);
|
||||
|
||||
|
@@ -464,12 +464,43 @@ RED.subflow = (function() {
|
||||
|
||||
$("#red-ui-subflow-delete").on("click", function(event) {
|
||||
event.preventDefault();
|
||||
var startDirty = RED.nodes.dirty();
|
||||
var historyEvent = removeSubflow(RED.workspaces.active());
|
||||
historyEvent.t = 'delete';
|
||||
historyEvent.dirty = startDirty;
|
||||
var subflow = RED.nodes.subflow(RED.workspaces.active());
|
||||
if (subflow.instances.length > 0) {
|
||||
var msg = $('<div>')
|
||||
$('<p>').text(RED._("subflow.subflowInstances",{count: subflow.instances.length})).appendTo(msg);
|
||||
$('<p>').text(RED._("subflow.confirmDelete")).appendTo(msg);
|
||||
var confirmDeleteNotification = RED.notify(msg, {
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons: [
|
||||
{
|
||||
text: RED._('common.label.cancel'),
|
||||
click: function() {
|
||||
confirmDeleteNotification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._('workspace.confirmDelete'),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
confirmDeleteNotification.close();
|
||||
completeDelete();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
RED.history.push(historyEvent);
|
||||
return;
|
||||
} else {
|
||||
completeDelete();
|
||||
}
|
||||
function completeDelete() {
|
||||
var startDirty = RED.nodes.dirty();
|
||||
var historyEvent = removeSubflow(RED.workspaces.active());
|
||||
historyEvent.t = 'delete';
|
||||
historyEvent.dirty = startDirty;
|
||||
RED.history.push(historyEvent);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
@@ -119,34 +119,17 @@ RED.sidebar.info.outliner = (function() {
|
||||
return div;
|
||||
}
|
||||
|
||||
function getSubflowLabel(n) {
|
||||
|
||||
var div = $('<div>',{class:"red-ui-info-outline-item"});
|
||||
RED.utils.createNodeIcon(n).appendTo(div);
|
||||
var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
|
||||
var labelText = getNodeLabelText(n);
|
||||
var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
|
||||
if (labelText) {
|
||||
label.text(labelText)
|
||||
} else {
|
||||
label.html(" ")
|
||||
}
|
||||
|
||||
addControls(n, div);
|
||||
|
||||
return div;
|
||||
|
||||
|
||||
// var div = $('<div>',{class:"red-ui-info-outline-item red-ui-info-outline-item-flow"});
|
||||
// var contentDiv = $('<div>',{class:"red-ui-search-result-description red-ui-info-outline-item-label"}).appendTo(div);
|
||||
// contentDiv.text(n.name || n.id);
|
||||
// addControls(n, div);
|
||||
// return div;
|
||||
}
|
||||
|
||||
function addControls(n,div) {
|
||||
var controls = $('<div>',{class:"red-ui-info-outline-item-controls red-ui-info-outline-item-hover-controls"}).appendTo(div);
|
||||
|
||||
if (n.type === "subflow") {
|
||||
var subflowInstanceBadge = $('<button type="button" class="red-ui-info-outline-item-control-users red-ui-button red-ui-button-small"><i class="fa fa-toggle-right"></i></button>').text(n.instances.length).appendTo(controls).on("click",function(evt) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
RED.search.show("type:subflow:"+n.id);
|
||||
})
|
||||
// RED.popover.tooltip(userCountBadge,function() { return RED._('editor.nodesUse',{count:n.users.length})});
|
||||
}
|
||||
if (n._def.category === "config" && n.type !== "group") {
|
||||
var userCountBadge = $('<button type="button" class="red-ui-info-outline-item-control-users red-ui-button red-ui-button-small"><i class="fa fa-toggle-right"></i></button>').text(n.users.length).appendTo(controls).on("click",function(evt) {
|
||||
evt.preventDefault();
|
||||
@@ -169,7 +152,7 @@ RED.sidebar.info.outliner = (function() {
|
||||
// evt.stopPropagation();
|
||||
// RED.view.reveal(n.id);
|
||||
// })
|
||||
if (n.type !== 'group' && n.type !== 'subflow') {
|
||||
if (n.type !== 'subflow') {
|
||||
var toggleButton = $('<button type="button" class="red-ui-info-outline-item-control-disable red-ui-button red-ui-button-small"><i class="fa fa-circle-thin"></i><i class="fa fa-ban"></i></button>').appendTo(controls).on("click",function(evt) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
@@ -179,6 +162,46 @@ RED.sidebar.info.outliner = (function() {
|
||||
} else {
|
||||
RED.workspaces.disable(n.id)
|
||||
}
|
||||
} else if (n.type === 'group') {
|
||||
var groupNodes = RED.group.getNodes(n,true);
|
||||
var groupHistoryEvent = {
|
||||
t:'multi',
|
||||
events:[],
|
||||
dirty: RED.nodes.dirty()
|
||||
}
|
||||
var targetState;
|
||||
groupNodes.forEach(function(n) {
|
||||
if (n.type !== 'group') {
|
||||
if (targetState === undefined) {
|
||||
targetState = !n.d;
|
||||
}
|
||||
var state = !!n.d;
|
||||
if (state !== targetState) {
|
||||
var historyEvent = {
|
||||
t: "edit",
|
||||
node: n,
|
||||
changed: n.changed,
|
||||
changes: {
|
||||
d: n.d
|
||||
}
|
||||
}
|
||||
if (n.d) {
|
||||
delete n.d;
|
||||
} else {
|
||||
n.d = true;
|
||||
}
|
||||
n.dirty = true;
|
||||
n.changed = true;
|
||||
RED.events.emit("nodes:change",n);
|
||||
groupHistoryEvent.events.push(historyEvent);
|
||||
}
|
||||
}
|
||||
if (groupHistoryEvent.events.length > 0) {
|
||||
RED.history.push(groupHistoryEvent);
|
||||
RED.nodes.dirty(true)
|
||||
RED.view.redraw();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// TODO: this ought to be a utility function in RED.nodes
|
||||
var historyEvent = {
|
||||
@@ -198,11 +221,15 @@ RED.sidebar.info.outliner = (function() {
|
||||
n.dirty = true;
|
||||
n.changed = true;
|
||||
RED.events.emit("nodes:change",n);
|
||||
RED.history.push(historyEvent);
|
||||
RED.nodes.dirty(true)
|
||||
RED.view.redraw();
|
||||
}
|
||||
});
|
||||
RED.popover.tooltip(toggleButton,function() {
|
||||
if (n.type === "group") {
|
||||
return RED._("common.label.enable")+" / "+RED._("common.label.disable")
|
||||
}
|
||||
return RED._("common.label."+(((n.type==='tab' && n.disabled) || (n.type!=='tab' && n.d))?"enable":"disable"));
|
||||
});
|
||||
} else {
|
||||
@@ -486,6 +513,13 @@ RED.sidebar.info.outliner = (function() {
|
||||
existingObject.treeList.remove();
|
||||
delete objects[n.id]
|
||||
|
||||
if (/^subflow:/.test(n.type)) {
|
||||
var sfType = n.type.substring(8);
|
||||
if (objects[sfType]) {
|
||||
objects[sfType].element.find(".red-ui-info-outline-item-control-users").text(RED.nodes.subflow(sfType).instances.length);
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a group being removed, it may have an empty item
|
||||
if (empties[n.id]) {
|
||||
delete empties[n.id];
|
||||
@@ -587,6 +621,12 @@ RED.sidebar.info.outliner = (function() {
|
||||
configNodeTypes[parent].types[n.type].treeList.addChild(objects[n.id]);
|
||||
}
|
||||
objects[n.id].element.toggleClass("red-ui-info-outline-item-disabled", !!n.d)
|
||||
if (/^subflow:/.test(n.type)) {
|
||||
var sfType = n.type.substring(8);
|
||||
if (objects[sfType]) {
|
||||
objects[sfType].element.find(".red-ui-info-outline-item-control-users").text(RED.nodes.subflow(sfType).instances.length);
|
||||
}
|
||||
}
|
||||
updateSearch();
|
||||
}
|
||||
|
||||
|
@@ -338,7 +338,7 @@ RED.sidebar.info = (function() {
|
||||
count++;
|
||||
propRow = $('<tr class="red-ui-help-info-property-row'+(expandedSections.property?"":" hide")+'"><td></td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[0]).text(n);
|
||||
if (defaults[n].type) {
|
||||
if (defaults[n].type && !defaults[n]._type.array) {
|
||||
var configNode = RED.nodes.node(val);
|
||||
if (!configNode) {
|
||||
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
|
||||
|
@@ -109,13 +109,19 @@ RED.userSettings = (function() {
|
||||
function compText(a, b) {
|
||||
return a.text.localeCompare(b.text);
|
||||
}
|
||||
|
||||
|
||||
var viewSettings = [
|
||||
{
|
||||
options: [
|
||||
{setting:"editor-language",local: true, label:"menu.label.view.language",options:function(done){ done([{val:'',text:RED._('menu.label.view.browserDefault')}].concat(RED.settings.theme("languages").map(localeToName).sort(compText))) }},
|
||||
]
|
||||
},{
|
||||
},
|
||||
// {
|
||||
// options: [
|
||||
// {setting:"theme", label:"Theme",options:function(done){ done([{val:'',text:'default'}].concat(RED.settings.theme("themes"))) }},
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
title: "menu.label.view.grid",
|
||||
options: [
|
||||
{setting:"view-show-grid",oldSetting:"menu-menu-item-view-show-grid",label:"menu.label.view.showGrid", default: true, toggle:true,onchange:"core:toggle-show-grid"},
|
||||
|
@@ -615,18 +615,25 @@ RED.utils = (function() {
|
||||
return element;
|
||||
}
|
||||
|
||||
function normalisePropertyExpression(str) {
|
||||
function createError(code, message) {
|
||||
var e = new Error(message);
|
||||
e.code = code;
|
||||
return e;
|
||||
}
|
||||
|
||||
function normalisePropertyExpression(str,msg) {
|
||||
// This must be kept in sync with validatePropertyExpression
|
||||
// in editor/js/ui/utils.js
|
||||
|
||||
var length = str.length;
|
||||
if (length === 0) {
|
||||
throw new Error("Invalid property expression: zero-length");
|
||||
throw createError("INVALID_EXPR","Invalid property expression: zero-length");
|
||||
}
|
||||
var parts = [];
|
||||
var start = 0;
|
||||
var inString = false;
|
||||
var inBox = false;
|
||||
var boxExpression = false;
|
||||
var quoteChar;
|
||||
var v;
|
||||
for (var i=0;i<length;i++) {
|
||||
@@ -634,14 +641,14 @@ RED.utils = (function() {
|
||||
if (!inString) {
|
||||
if (c === "'" || c === '"') {
|
||||
if (i != start) {
|
||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||
}
|
||||
inString = true;
|
||||
quoteChar = c;
|
||||
start = i+1;
|
||||
} else if (c === '.') {
|
||||
if (i===0) {
|
||||
throw new Error("Invalid property expression: unexpected . at position 0");
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected . at position 0");
|
||||
}
|
||||
if (start != i) {
|
||||
v = str.substring(start,i);
|
||||
@@ -652,57 +659,99 @@ RED.utils = (function() {
|
||||
}
|
||||
}
|
||||
if (i===length-1) {
|
||||
throw new Error("Invalid property expression: unterminated expression");
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||
}
|
||||
// Next char is first char of an identifier: a-z 0-9 $ _
|
||||
if (!/[a-z0-9\$\_]/i.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
}
|
||||
start = i+1;
|
||||
} else if (c === '[') {
|
||||
if (i === 0) {
|
||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||
}
|
||||
if (start != i) {
|
||||
parts.push(str.substring(start,i));
|
||||
}
|
||||
if (i===length-1) {
|
||||
throw new Error("Invalid property expression: unterminated expression");
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||
}
|
||||
// Next char is either a quote or a number
|
||||
if (!/["'\d]/.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
// Start of a new expression. If it starts with msg it is a nested expression
|
||||
// Need to scan ahead to find the closing bracket
|
||||
if (/^msg[.\[]/.test(str.substring(i+1))) {
|
||||
var depth = 1;
|
||||
var inLocalString = false;
|
||||
var localStringQuote;
|
||||
for (var j=i+1;j<length;j++) {
|
||||
if (/["']/.test(str[j])) {
|
||||
if (inLocalString) {
|
||||
if (str[j] === localStringQuote) {
|
||||
inLocalString = false
|
||||
}
|
||||
} else {
|
||||
inLocalString = true;
|
||||
localStringQuote = str[j]
|
||||
}
|
||||
}
|
||||
if (str[j] === '[') {
|
||||
depth++;
|
||||
} else if (str[j] === ']') {
|
||||
depth--;
|
||||
}
|
||||
if (depth === 0) {
|
||||
try {
|
||||
if (msg) {
|
||||
parts.push(getMessageProperty(msg, str.substring(i+1,j)))
|
||||
} else {
|
||||
parts.push(normalisePropertyExpression(str.substring(i+1,j), msg));
|
||||
}
|
||||
inBox = false;
|
||||
i = j;
|
||||
start = j+1;
|
||||
break;
|
||||
} catch(err) {
|
||||
throw createError("INVALID_EXPR","Invalid expression started at position "+(i+1))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (depth > 0) {
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unmatched '[' at position "+i);
|
||||
}
|
||||
continue;
|
||||
} else if (!/["'\d]/.test(str[i+1])) {
|
||||
// Next char is either a quote or a number
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
}
|
||||
start = i+1;
|
||||
inBox = true;
|
||||
} else if (c === ']') {
|
||||
if (!inBox) {
|
||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||
}
|
||||
if (start != i) {
|
||||
v = str.substring(start,i);
|
||||
if (/^\d+$/.test(v)) {
|
||||
parts.push(parseInt(v));
|
||||
} else {
|
||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start);
|
||||
}
|
||||
}
|
||||
start = i+1;
|
||||
inBox = false;
|
||||
} else if (c === ' ') {
|
||||
throw new Error("Invalid property expression: unexpected ' ' at position "+i);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected ' ' at position "+i);
|
||||
}
|
||||
} else {
|
||||
if (c === quoteChar) {
|
||||
if (i-start === 0) {
|
||||
throw new Error("Invalid property expression: zero-length string at position "+start);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: zero-length string at position "+start);
|
||||
}
|
||||
parts.push(str.substring(start,i));
|
||||
// If inBox, next char must be a ]. Otherwise it may be [ or .
|
||||
if (inBox && !/\]/.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start);
|
||||
} else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1));
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1));
|
||||
}
|
||||
start = i+1;
|
||||
inString = false;
|
||||
@@ -711,7 +760,7 @@ RED.utils = (function() {
|
||||
|
||||
}
|
||||
if (inBox || inString) {
|
||||
throw new Error("Invalid property expression: unterminated expression");
|
||||
throw new createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||
}
|
||||
if (start < length) {
|
||||
parts.push(str.substring(start));
|
||||
|
@@ -2276,7 +2276,7 @@ RED.view = (function() {
|
||||
}
|
||||
|
||||
function calculateTextWidth(str, className) {
|
||||
var result=convertLineBreakCharacter(str);
|
||||
var result = convertLineBreakCharacter(str);
|
||||
var width = 0;
|
||||
for (var i=0;i<result.length;i++) {
|
||||
var calculateTextW=calculateTextDimensions(result[i],className)[0];
|
||||
|
Reference in New Issue
Block a user