mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
merge to latest
This commit is contained in:
commit
522360dcb7
BIN
editor/images/typedInput/env.png
Normal file
BIN
editor/images/typedInput/env.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 809 B |
@ -433,8 +433,8 @@ var RED = (function() {
|
|||||||
{id:"menu-item-import-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-import-dialog"},
|
{id:"menu-item-import-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-import-dialog"},
|
||||||
{id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]}
|
{id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]}
|
||||||
]});
|
]});
|
||||||
menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),disabled:true,options:[
|
menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),options:[
|
||||||
{id:"menu-item-export-clipboard",label:RED._("menu.label.clipboard"),disabled:true,onselect:"core:show-export-dialog"},
|
{id:"menu-item-export-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-export-dialog"},
|
||||||
{id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:"core:library-export"}
|
{id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:"core:library-export"}
|
||||||
]});
|
]});
|
||||||
menuOptions.push(null);
|
menuOptions.push(null);
|
||||||
|
@ -309,18 +309,6 @@ RED.clipboard = (function() {
|
|||||||
|
|
||||||
$('<input type="text" id="clipboard-hidden">').appendTo("body");
|
$('<input type="text" id="clipboard-hidden">').appendTo("body");
|
||||||
|
|
||||||
RED.events.on("view:selection-changed",function(selection) {
|
|
||||||
if (!selection.nodes) {
|
|
||||||
RED.menu.setDisabled("menu-item-export",true);
|
|
||||||
RED.menu.setDisabled("menu-item-export-clipboard",true);
|
|
||||||
RED.menu.setDisabled("menu-item-export-library",true);
|
|
||||||
} else {
|
|
||||||
RED.menu.setDisabled("menu-item-export",false);
|
|
||||||
RED.menu.setDisabled("menu-item-export-clipboard",false);
|
|
||||||
RED.menu.setDisabled("menu-item-export-library",false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
RED.actions.add("core:show-export-dialog",exportNodes);
|
RED.actions.add("core:show-export-dialog",exportNodes);
|
||||||
RED.actions.add("core:show-import-dialog",importNodes);
|
RED.actions.add("core:show-import-dialog",importNodes);
|
||||||
|
|
||||||
|
@ -19,12 +19,14 @@ RED.popover = (function() {
|
|||||||
"default": {
|
"default": {
|
||||||
top: 10,
|
top: 10,
|
||||||
leftRight: 17,
|
leftRight: 17,
|
||||||
leftLeft: 25
|
leftLeft: 25,
|
||||||
|
leftBottom: 8,
|
||||||
},
|
},
|
||||||
"small": {
|
"small": {
|
||||||
top: 5,
|
top: 5,
|
||||||
leftRight: 17,
|
leftRight: 17,
|
||||||
leftLeft: 16
|
leftLeft: 16,
|
||||||
|
leftBottom: 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function createPopover(options) {
|
function createPopover(options) {
|
||||||
@ -69,6 +71,8 @@ RED.popover = (function() {
|
|||||||
div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left+targetWidth+deltaSizes[size].leftRight});
|
div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left+targetWidth+deltaSizes[size].leftRight});
|
||||||
} else if (direction === 'left') {
|
} else if (direction === 'left') {
|
||||||
div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left-deltaSizes[size].leftLeft-divWidth});
|
div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left-deltaSizes[size].leftLeft-divWidth});
|
||||||
|
} else if (direction === 'bottom') {
|
||||||
|
div.css({top: targetPos.top+targetHeight+deltaSizes[size].top,left:targetPos.left+targetWidth/2-divWidth/2 - deltaSizes[size].leftBottom});
|
||||||
}
|
}
|
||||||
if (instant) {
|
if (instant) {
|
||||||
div.show();
|
div.show();
|
||||||
|
@ -19,8 +19,10 @@
|
|||||||
RED.tabs = (function() {
|
RED.tabs = (function() {
|
||||||
function createTabs(options) {
|
function createTabs(options) {
|
||||||
var tabs = {};
|
var tabs = {};
|
||||||
|
var pinnedTabsCount = 0;
|
||||||
var currentTabWidth;
|
var currentTabWidth;
|
||||||
var currentActiveTabWidth = 0;
|
var currentActiveTabWidth = 0;
|
||||||
|
var collapsibleMenu;
|
||||||
|
|
||||||
var ul = options.element || $("#"+options.id);
|
var ul = options.element || $("#"+options.id);
|
||||||
var wrapper = ul.wrap( "<div>" ).parent();
|
var wrapper = ul.wrap( "<div>" ).parent();
|
||||||
@ -50,6 +52,55 @@ RED.tabs = (function() {
|
|||||||
scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a");
|
scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a");
|
||||||
scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') }).on('click',function(evt){ evt.preventDefault();});
|
scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') }).on('click',function(evt){ evt.preventDefault();});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.collapsible) {
|
||||||
|
// var dropDown = $('<div>',{class:"red-ui-tabs-select"}).appendTo(wrapper);
|
||||||
|
// ul.hide();
|
||||||
|
wrapper.addClass("red-ui-tabs-collapsible");
|
||||||
|
|
||||||
|
var collapsedButtonsRow = $('<div class="red-ui-tab-link-buttons"></div>').appendTo(wrapper);
|
||||||
|
|
||||||
|
var selectButton = $('<a href="#"><i class="fa fa-caret-down"></i></a>').appendTo(collapsedButtonsRow);
|
||||||
|
selectButton.addClass("red-ui-tab-link-button-menu")
|
||||||
|
selectButton.click(function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
if (!collapsibleMenu) {
|
||||||
|
var pinnedOptions = [];
|
||||||
|
var options = [];
|
||||||
|
ul.children().each(function(i,el) {
|
||||||
|
var id = $(el).data('tabId');
|
||||||
|
var opt = {
|
||||||
|
id:"red-ui-tabs-menu-option-"+id,
|
||||||
|
label: tabs[id].name,
|
||||||
|
onselect: function() {
|
||||||
|
activateTab(id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (tabs[id].pinned) {
|
||||||
|
pinnedOptions.push(opt);
|
||||||
|
} else {
|
||||||
|
options.push(opt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
options = pinnedOptions.concat(options);
|
||||||
|
collapsibleMenu = RED.menu.init({id:"debug-message-option-menu",options: options});
|
||||||
|
collapsibleMenu.css({
|
||||||
|
position: "absolute"
|
||||||
|
})
|
||||||
|
collapsibleMenu.on('mouseleave', function(){ $(this).hide() });
|
||||||
|
collapsibleMenu.on('mouseup', function() { $(this).hide() });
|
||||||
|
collapsibleMenu.appendTo("body");
|
||||||
|
var elementPos = selectButton.offset();
|
||||||
|
collapsibleMenu.css({
|
||||||
|
top: (elementPos.top+selectButton.height()-20)+"px",
|
||||||
|
left: (elementPos.left - collapsibleMenu.width() + selectButton.width())+"px"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
collapsibleMenu.toggle();
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function scrollEventHandler(evt,dir) {
|
function scrollEventHandler(evt,dir) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
if ($(this).hasClass('disabled')) {
|
if ($(this).hasClass('disabled')) {
|
||||||
@ -118,6 +169,9 @@ RED.tabs = (function() {
|
|||||||
ul.children().removeClass("active");
|
ul.children().removeClass("active");
|
||||||
ul.children().css({"transition": "width 100ms"});
|
ul.children().css({"transition": "width 100ms"});
|
||||||
link.parent().addClass("active");
|
link.parent().addClass("active");
|
||||||
|
var parentId = link.parent().attr('id');
|
||||||
|
wrapper.find(".red-ui-tab-link-button").removeClass("active");
|
||||||
|
$("#"+parentId+"-link-button").addClass("active");
|
||||||
if (options.scrollable) {
|
if (options.scrollable) {
|
||||||
var pos = link.parent().position().left;
|
var pos = link.parent().position().left;
|
||||||
if (pos-21 < 0) {
|
if (pos-21 < 0) {
|
||||||
@ -155,6 +209,30 @@ RED.tabs = (function() {
|
|||||||
var tabs = ul.find("li.red-ui-tab");
|
var tabs = ul.find("li.red-ui-tab");
|
||||||
var width = wrapper.width();
|
var width = wrapper.width();
|
||||||
var tabCount = tabs.size();
|
var tabCount = tabs.size();
|
||||||
|
var tabWidth;
|
||||||
|
|
||||||
|
if (options.collapsible) {
|
||||||
|
tabWidth = width - collapsedButtonsRow.width()-10;
|
||||||
|
if (tabWidth < 198) {
|
||||||
|
var delta = 198 - tabWidth;
|
||||||
|
var b = collapsedButtonsRow.find("a:last").prev();
|
||||||
|
while (b.is(":not(:visible)")) {
|
||||||
|
b = b.prev();
|
||||||
|
}
|
||||||
|
if (!b.hasClass("red-ui-tab-link-button-pinned")) {
|
||||||
|
b.hide();
|
||||||
|
}
|
||||||
|
tabWidth = width - collapsedButtonsRow.width()-10;
|
||||||
|
} else {
|
||||||
|
var space = width - 198 - collapsedButtonsRow.width();
|
||||||
|
if (space > 40) {
|
||||||
|
collapsedButtonsRow.find("a:not(:visible):first").show();
|
||||||
|
tabWidth = width - collapsedButtonsRow.width()-10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tabs.css({width:tabWidth});
|
||||||
|
|
||||||
|
} else {
|
||||||
var tabWidth = (width-12-(tabCount*6))/tabCount;
|
var tabWidth = (width-12-(tabCount*6))/tabCount;
|
||||||
currentTabWidth = (100*tabWidth/width)+"%";
|
currentTabWidth = (100*tabWidth/width)+"%";
|
||||||
currentActiveTabWidth = currentTabWidth+"%";
|
currentActiveTabWidth = currentTabWidth+"%";
|
||||||
@ -175,6 +253,10 @@ RED.tabs = (function() {
|
|||||||
currentActiveTabWidth = 0;
|
currentActiveTabWidth = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (options.collapsible) {
|
||||||
|
console.log(currentTabWidth);
|
||||||
|
}
|
||||||
|
|
||||||
tabs.css({width:currentTabWidth});
|
tabs.css({width:currentTabWidth});
|
||||||
if (tabWidth < 50) {
|
if (tabWidth < 50) {
|
||||||
ul.find(".red-ui-tab-close").hide();
|
ul.find(".red-ui-tab-close").hide();
|
||||||
@ -191,6 +273,7 @@ RED.tabs = (function() {
|
|||||||
ul.find("li.red-ui-tab.active .red-ui-tab-icon").show();
|
ul.find("li.red-ui-tab.active .red-ui-tab-icon").show();
|
||||||
ul.find("li.red-ui-tab.active .red-ui-tab-label").css({paddingLeft:""})
|
ul.find("li.red-ui-tab.active .red-ui-tab-label").css({paddingLeft:""})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,11 +293,15 @@ RED.tabs = (function() {
|
|||||||
activateTab(tab.find("a"));
|
activateTab(tab.find("a"));
|
||||||
}
|
}
|
||||||
li.remove();
|
li.remove();
|
||||||
|
if (tabs[id].pinned) {
|
||||||
|
pinnedTabsCount--;
|
||||||
|
}
|
||||||
if (options.onremove) {
|
if (options.onremove) {
|
||||||
options.onremove(tabs[id]);
|
options.onremove(tabs[id]);
|
||||||
}
|
}
|
||||||
delete tabs[id];
|
delete tabs[id];
|
||||||
updateTabWidths();
|
updateTabWidths();
|
||||||
|
collapsibleMenu = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -223,13 +310,55 @@ RED.tabs = (function() {
|
|||||||
var li = $("<li/>",{class:"red-ui-tab"}).appendTo(ul);
|
var li = $("<li/>",{class:"red-ui-tab"}).appendTo(ul);
|
||||||
li.attr('id',"red-ui-tab-"+(tab.id.replace(".","-")));
|
li.attr('id',"red-ui-tab-"+(tab.id.replace(".","-")));
|
||||||
li.data("tabId",tab.id);
|
li.data("tabId",tab.id);
|
||||||
|
|
||||||
|
if (options.maximumTabWidth) {
|
||||||
|
li.css("maxWidth",options.maximumTabWidth+"px");
|
||||||
|
}
|
||||||
var link = $("<a/>",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li);
|
var link = $("<a/>",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li);
|
||||||
if (tab.icon) {
|
if (tab.icon) {
|
||||||
$('<img src="'+tab.icon+'" class="red-ui-tab-icon"/>').appendTo(link);
|
$('<img src="'+tab.icon+'" class="red-ui-tab-icon"/>').appendTo(link);
|
||||||
|
} else if (tab.iconClass) {
|
||||||
|
$('<i>',{class:"red-ui-tab-icon "+tab.iconClass}).appendTo(link);
|
||||||
}
|
}
|
||||||
var span = $('<span/>',{class:"bidiAware"}).text(tab.label).appendTo(link);
|
var span = $('<span/>',{class:"bidiAware"}).text(tab.label).appendTo(link);
|
||||||
span.attr('dir', RED.text.bidi.resolveBaseTextDir(tab.label));
|
span.attr('dir', RED.text.bidi.resolveBaseTextDir(tab.label));
|
||||||
|
if (options.collapsible) {
|
||||||
|
li.addClass("red-ui-tab-pinned");
|
||||||
|
var pinnedLink = $('<a href="#'+tab.id+'" class="red-ui-tab-link-button"></a>');
|
||||||
|
if (tab.pinned) {
|
||||||
|
if (pinnedTabsCount === 0) {
|
||||||
|
pinnedLink.prependTo(collapsedButtonsRow)
|
||||||
|
} else {
|
||||||
|
pinnedLink.insertAfter(collapsedButtonsRow.find("a.red-ui-tab-link-button-pinned:last"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pinnedLink.insertBefore(collapsedButtonsRow.find("a:last"));
|
||||||
|
}
|
||||||
|
|
||||||
|
pinnedLink.attr('id',li.attr('id')+"-link-button");
|
||||||
|
if (tab.iconClass) {
|
||||||
|
$('<i>',{class:tab.iconClass}).appendTo(pinnedLink);
|
||||||
|
} else {
|
||||||
|
$('<i>',{class:"fa fa-lemon-o"}).appendTo(pinnedLink);
|
||||||
|
}
|
||||||
|
pinnedLink.click(function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
activateTab(tab.id);
|
||||||
|
});
|
||||||
|
if (tab.pinned) {
|
||||||
|
pinnedLink.addClass("red-ui-tab-link-button-pinned");
|
||||||
|
pinnedTabsCount++;
|
||||||
|
}
|
||||||
|
RED.popover.create({
|
||||||
|
target:$(pinnedLink),
|
||||||
|
trigger: "hover",
|
||||||
|
size: "small",
|
||||||
|
direction: "bottom",
|
||||||
|
content: tab.name,
|
||||||
|
delay: { show: 550, hide: 10 }
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
link.on("click",onTabClick);
|
link.on("click",onTabClick);
|
||||||
link.on("dblclick",onTabDblClick);
|
link.on("dblclick",onTabDblClick);
|
||||||
if (tab.closeable) {
|
if (tab.closeable) {
|
||||||
@ -326,6 +455,7 @@ RED.tabs = (function() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
collapsibleMenu = null;
|
||||||
},
|
},
|
||||||
removeTab: removeTab,
|
removeTab: removeTab,
|
||||||
activateTab: activateTab,
|
activateTab: activateTab,
|
||||||
|
@ -76,6 +76,11 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
value: "env",
|
||||||
|
label: "env variable",
|
||||||
|
icon: "red/images/typedInput/env.png"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var nlsd = false;
|
var nlsd = false;
|
||||||
|
@ -425,12 +425,8 @@ RED.library = (function() {
|
|||||||
|
|
||||||
RED.events.on("view:selection-changed",function(selection) {
|
RED.events.on("view:selection-changed",function(selection) {
|
||||||
if (!selection.nodes) {
|
if (!selection.nodes) {
|
||||||
RED.menu.setDisabled("menu-item-export",true);
|
|
||||||
RED.menu.setDisabled("menu-item-export-clipboard",true);
|
|
||||||
RED.menu.setDisabled("menu-item-export-library",true);
|
RED.menu.setDisabled("menu-item-export-library",true);
|
||||||
} else {
|
} else {
|
||||||
RED.menu.setDisabled("menu-item-export",false);
|
|
||||||
RED.menu.setDisabled("menu-item-export-clipboard",false);
|
|
||||||
RED.menu.setDisabled("menu-item-export-library",false);
|
RED.menu.setDisabled("menu-item-export-library",false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1003,6 +1003,8 @@ RED.sidebar.versionControl = (function() {
|
|||||||
name: "Project History",
|
name: "Project History",
|
||||||
content: sidebarContent,
|
content: sidebarContent,
|
||||||
enableOnEdit: false,
|
enableOnEdit: false,
|
||||||
|
pinned: true,
|
||||||
|
iconClass: "fa fa-code-fork",
|
||||||
onchange: function() {
|
onchange: function() {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
sections.resize();
|
sections.resize();
|
||||||
|
@ -35,7 +35,8 @@ RED.sidebar = (function() {
|
|||||||
tab.onremove.call(tab);
|
tab.onremove.call(tab);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
minimumActiveTabWidth: 70
|
// minimumActiveTabWidth: 70,
|
||||||
|
collapsible: true
|
||||||
// scrollable: true
|
// scrollable: true
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -59,6 +60,8 @@ RED.sidebar = (function() {
|
|||||||
options = title;
|
options = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete options.closeable;
|
||||||
|
|
||||||
options.wrapper = $('<div>',{style:"height:100%"}).appendTo("#sidebar-content")
|
options.wrapper = $('<div>',{style:"height:100%"}).appendTo("#sidebar-content")
|
||||||
options.wrapper.append(options.content);
|
options.wrapper.append(options.content);
|
||||||
options.wrapper.hide();
|
options.wrapper.hide();
|
||||||
@ -82,6 +85,8 @@ RED.sidebar = (function() {
|
|||||||
group: "sidebar-tabs"
|
group: "sidebar-tabs"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.iconClass = options.iconClass || "fa fa-square-o"
|
||||||
|
|
||||||
knownTabs[options.id] = options;
|
knownTabs[options.id] = options;
|
||||||
|
|
||||||
if (options.visible !== false) {
|
if (options.visible !== false) {
|
||||||
|
@ -221,8 +221,7 @@ RED.sidebar.config = (function() {
|
|||||||
name: RED._("sidebar.config.name"),
|
name: RED._("sidebar.config.name"),
|
||||||
content: content,
|
content: content,
|
||||||
toolbar: toolbar,
|
toolbar: toolbar,
|
||||||
closeable: true,
|
iconClass: "fa fa-cog",
|
||||||
visible: false,
|
|
||||||
onchange: function() { refreshConfigNodeList(); }
|
onchange: function() { refreshConfigNodeList(); }
|
||||||
});
|
});
|
||||||
RED.actions.add("core:show-config-tab",function() {RED.sidebar.show('config')});
|
RED.actions.add("core:show-config-tab",function() {RED.sidebar.show('config')});
|
||||||
|
@ -83,7 +83,9 @@ RED.sidebar.info = (function() {
|
|||||||
id: "info",
|
id: "info",
|
||||||
label: RED._("sidebar.info.label"),
|
label: RED._("sidebar.info.label"),
|
||||||
name: RED._("sidebar.info.name"),
|
name: RED._("sidebar.info.name"),
|
||||||
|
iconClass: "fa fa-info",
|
||||||
content: content,
|
content: content,
|
||||||
|
pinned: true,
|
||||||
enableOnEdit: true
|
enableOnEdit: true
|
||||||
});
|
});
|
||||||
if (tips.enabled()) {
|
if (tips.enabled()) {
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-popover:after, .red-ui-popover:before {
|
.red-ui-popover:after, .red-ui-popover:before {
|
||||||
top: 50%;
|
|
||||||
border: solid transparent;
|
border: solid transparent;
|
||||||
content: " ";
|
content: " ";
|
||||||
height: 0;
|
height: 0;
|
||||||
@ -39,12 +38,18 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.red-ui-popover.red-ui-popover-right:after, .red-ui-popover.red-ui-popover-right:before {
|
.red-ui-popover.red-ui-popover-right:after, .red-ui-popover.red-ui-popover-right:before {
|
||||||
|
top: 50%;
|
||||||
right: 100%;
|
right: 100%;
|
||||||
}
|
}
|
||||||
.red-ui-popover.red-ui-popover-left:after, .red-ui-popover.red-ui-popover-left:before {
|
.red-ui-popover.red-ui-popover-left:after, .red-ui-popover.red-ui-popover-left:before {
|
||||||
|
top: 50%;
|
||||||
left: 100%;
|
left: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red-ui-popover.red-ui-popover-bottom:after, .red-ui-popover.red-ui-popover-bottom:before {
|
||||||
|
bottom: 100%;
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
.red-ui-popover.red-ui-popover-right:after {
|
.red-ui-popover.red-ui-popover-right:after {
|
||||||
border-color: rgba(136, 183, 213, 0);
|
border-color: rgba(136, 183, 213, 0);
|
||||||
@ -72,6 +77,21 @@
|
|||||||
margin-top: -11px;
|
margin-top: -11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.red-ui-popover.red-ui-popover-bottom:after {
|
||||||
|
border-color: rgba(136, 183, 213, 0);
|
||||||
|
border-bottom-color: #fff;
|
||||||
|
border-width: 10px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
.red-ui-popover.red-ui-popover-bottom:before {
|
||||||
|
border-color: rgba(194, 225, 245, 0);
|
||||||
|
border-bottom-color: $primary-border-color;
|
||||||
|
border-width: 11px;
|
||||||
|
margin-left: -11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.red-ui-popover-size-small {
|
.red-ui-popover-size-small {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@ -93,4 +113,12 @@
|
|||||||
border-width: 6px;
|
border-width: 6px;
|
||||||
margin-top: -6px;
|
margin-top: -6px;
|
||||||
}
|
}
|
||||||
|
&.red-ui-popover-bottom:after {
|
||||||
|
border-width: 5px;
|
||||||
|
margin-left: -5px;
|
||||||
|
}
|
||||||
|
&.red-ui-popover-bottom:before {
|
||||||
|
border-width: 6px;
|
||||||
|
margin-left: -6px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
color: $workspace-button-color-hover;
|
color: $workspace-button-color-hover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.red-ui-tab-icon {
|
img.red-ui-tab-icon {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,6 +113,21 @@
|
|||||||
&.red-ui-tabs-add.red-ui-tabs-scrollable {
|
&.red-ui-tabs-add.red-ui-tabs-scrollable {
|
||||||
padding-right: 59px;
|
padding-right: 59px;
|
||||||
}
|
}
|
||||||
|
&.red-ui-tabs-collapsible {
|
||||||
|
li:not(.active) {
|
||||||
|
display: none;
|
||||||
|
&.red-ui-tab-pinned {
|
||||||
|
a {
|
||||||
|
padding-left: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.red-ui-tabs-vertical {
|
&.red-ui-tabs-vertical {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -157,6 +172,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.red-ui-tabs-select {
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
opacity: 0.4;
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.red-ui-tab-button {
|
.red-ui-tab-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -180,7 +204,33 @@
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.red-ui-tab-link-buttons {
|
||||||
|
position: absolute;
|
||||||
|
box-sizing: border-box;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 35px;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid $primary-border-color;
|
||||||
|
z-index: 2;
|
||||||
|
a {
|
||||||
|
@include workspace-button;
|
||||||
|
line-height: 26px;
|
||||||
|
height: 28px;
|
||||||
|
width: 28px;
|
||||||
|
margin: 4px 3px 3px;
|
||||||
|
border: 1px solid $primary-border-color;
|
||||||
|
z-index: 2;
|
||||||
|
&.red-ui-tab-link-button {
|
||||||
|
&:not(.active) {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.red-ui-tab-link-button-menu {
|
||||||
|
border-color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.red-ui-tab-scroll {
|
.red-ui-tab-scroll {
|
||||||
width: 21px;
|
width: 21px;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -216,7 +266,7 @@
|
|||||||
right: 38px;
|
right: 38px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-ui-tab-icon {
|
img.red-ui-tab-icon {
|
||||||
margin-left: -8px;
|
margin-left: -8px;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
@ -225,6 +275,11 @@
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
i.red-ui-tab-icon {
|
||||||
|
opacity: 0.7;
|
||||||
|
width: 18px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.red-ui-tabs-badges {
|
.red-ui-tabs-badges {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
1
editor/vendor/jsonata/formatter.js
vendored
1
editor/vendor/jsonata/formatter.js
vendored
@ -117,6 +117,7 @@
|
|||||||
'$contains':{ args:[ 'str', 'pattern' ]},
|
'$contains':{ args:[ 'str', 'pattern' ]},
|
||||||
'$count':{ args:[ 'array' ]},
|
'$count':{ args:[ 'array' ]},
|
||||||
'$each':{ args:[ 'object', 'function' ]},
|
'$each':{ args:[ 'object', 'function' ]},
|
||||||
|
'$env': { args:[ 'arg' ]},
|
||||||
'$exists':{ args:[ 'arg' ]},
|
'$exists':{ args:[ 'arg' ]},
|
||||||
'$filter':{ args:[ 'array', 'function' ]},
|
'$filter':{ args:[ 'array', 'function' ]},
|
||||||
'$floor':{ args:[ 'number' ]},
|
'$floor':{ args:[ 'number' ]},
|
||||||
|
@ -263,7 +263,7 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
|||||||
$("#node-input-payload").typedInput({
|
$("#node-input-payload").typedInput({
|
||||||
default: 'str',
|
default: 'str',
|
||||||
typeField: $("#node-input-payloadType"),
|
typeField: $("#node-input-payloadType"),
|
||||||
types:['flow','global','str','num','bool','json','bin','date']
|
types:['flow','global','str','num','bool','json','bin','date','env']
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#inject-time-type-select").change(function() {
|
$("#inject-time-type-select").change(function() {
|
||||||
|
@ -154,7 +154,9 @@
|
|||||||
name: this._("debug.sidebar.name"),
|
name: this._("debug.sidebar.name"),
|
||||||
content: uiComponents.content,
|
content: uiComponents.content,
|
||||||
toolbar: uiComponents.footer,
|
toolbar: uiComponents.footer,
|
||||||
enableOnEdit: true
|
enableOnEdit: true,
|
||||||
|
pinned: true,
|
||||||
|
iconClass: "fa fa-wrench"
|
||||||
});
|
});
|
||||||
RED.actions.add("core:show-debug-tab",function() { RED.sidebar.show('debug'); });
|
RED.actions.add("core:show-debug-tab",function() { RED.sidebar.show('debug'); });
|
||||||
|
|
||||||
|
@ -230,12 +230,12 @@
|
|||||||
selectField.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t));
|
selectField.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var valueField = $('<input/>',{class:"node-input-rule-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata',previousValueType]});
|
var valueField = $('<input/>',{class:"node-input-rule-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||||
var numValueField = $('<input/>',{class:"node-input-rule-num-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['flow','global','num','jsonata']});
|
var numValueField = $('<input/>',{class:"node-input-rule-num-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['flow','global','num','jsonata','env']});
|
||||||
var expValueField = $('<input/>',{class:"node-input-rule-exp-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'jsonata',types:['jsonata']});
|
var expValueField = $('<input/>',{class:"node-input-rule-exp-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'jsonata',types:['jsonata']});
|
||||||
var btwnValueField = $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata',previousValueType]});
|
var btwnValueField = $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||||
var btwnAndLabel = $('<span/>',{class:"node-input-rule-btwn-label"}).text(" "+andLabel+" ").appendTo(row3);
|
var btwnAndLabel = $('<span/>',{class:"node-input-rule-btwn-label"}).text(" "+andLabel+" ").appendTo(row3);
|
||||||
var btwnValue2Field = $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata',previousValueType]});
|
var btwnValue2Field = $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||||
var typeValueField = $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"margin-left: 5px;"}).appendTo(row)
|
var typeValueField = $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"margin-left: 5px;"}).appendTo(row)
|
||||||
.typedInput({default:'string',types:[
|
.typedInput({default:'string',types:[
|
||||||
{value:"string",label:"string",hasValue:false},
|
{value:"string",label:"string",hasValue:false},
|
||||||
|
@ -146,7 +146,7 @@
|
|||||||
.appendTo(row2);
|
.appendTo(row2);
|
||||||
var propertyValue = $('<input/>',{class:"node-input-rule-property-value",type:"text"})
|
var propertyValue = $('<input/>',{class:"node-input-rule-property-value",type:"text"})
|
||||||
.appendTo(row2)
|
.appendTo(row2)
|
||||||
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata']});
|
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']});
|
||||||
|
|
||||||
var row3_1 = $('<div/>').appendTo(row3);
|
var row3_1 = $('<div/>').appendTo(row3);
|
||||||
$('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
|
$('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
|
||||||
@ -154,7 +154,7 @@
|
|||||||
.appendTo(row3_1);
|
.appendTo(row3_1);
|
||||||
var fromValue = $('<input/>',{class:"node-input-rule-property-search-value",type:"text"})
|
var fromValue = $('<input/>',{class:"node-input-rule-property-search-value",type:"text"})
|
||||||
.appendTo(row3_1)
|
.appendTo(row3_1)
|
||||||
.typedInput({default:'str',types:['msg','flow','global','str','re','num','bool']});
|
.typedInput({default:'str',types:['msg','flow','global','str','re','num','bool','env']});
|
||||||
|
|
||||||
var row3_2 = $('<div/>',{style:"margin-top:8px;"}).appendTo(row3);
|
var row3_2 = $('<div/>',{style:"margin-top:8px;"}).appendTo(row3);
|
||||||
$('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
|
$('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
|
||||||
@ -162,7 +162,7 @@
|
|||||||
.appendTo(row3_2);
|
.appendTo(row3_2);
|
||||||
var toValue = $('<input/>',{class:"node-input-rule-property-replace-value",type:"text"})
|
var toValue = $('<input/>',{class:"node-input-rule-property-replace-value",type:"text"})
|
||||||
.appendTo(row3_2)
|
.appendTo(row3_2)
|
||||||
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin']});
|
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','env']});
|
||||||
|
|
||||||
$('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
|
$('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
|
||||||
.text(to)
|
.text(to)
|
||||||
|
@ -93,6 +93,8 @@ module.exports = function(RED) {
|
|||||||
valid = false;
|
valid = false;
|
||||||
this.error(RED._("change.errors.invalid-expr",{error:e.message}));
|
this.error(RED._("change.errors.invalid-expr",{error:e.message}));
|
||||||
}
|
}
|
||||||
|
} else if (rule.tot === 'env') {
|
||||||
|
rule.to = RED.util.evaluateNodeProperty(rule.to,'env');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,11 +190,11 @@
|
|||||||
},
|
},
|
||||||
"$flowContext": {
|
"$flowContext": {
|
||||||
"args": "string",
|
"args": "string",
|
||||||
"desc": "Retrieves a flow context property."
|
"desc": "Retrieves a flow context property.\n\nThis is a Node-RED defined function."
|
||||||
},
|
},
|
||||||
"$globalContext": {
|
"$globalContext": {
|
||||||
"args": "string",
|
"args": "string",
|
||||||
"desc": "Retrieves a global context property."
|
"desc": "Retrieves a global context property.\n\nThis is a Node-RED defined function."
|
||||||
},
|
},
|
||||||
"$pad": {
|
"$pad": {
|
||||||
"args": "string, width [, char]",
|
"args": "string, width [, char]",
|
||||||
@ -215,5 +215,9 @@
|
|||||||
"$toMillis": {
|
"$toMillis": {
|
||||||
"args": "timestamp",
|
"args": "timestamp",
|
||||||
"desc": "Convert a `timestamp` string in the ISO 8601 format to the number of milliseconds since the Unix Epoch (1 January, 1970 UTC) as a number. An error is thrown if the string is not in the correct format."
|
"desc": "Convert a `timestamp` string in the ISO 8601 format to the number of milliseconds since the Unix Epoch (1 January, 1970 UTC) as a number. An error is thrown if the string is not in the correct format."
|
||||||
|
},
|
||||||
|
"$env": {
|
||||||
|
"args": "arg",
|
||||||
|
"desc": "Returns the value of an environment variable.\n\nThis is a Node-RED defined function."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,17 @@ function copyObjectProperties(src,dst,copyList,blockList) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function requireModule(name) {
|
||||||
|
var moduleInfo = registry.getModuleInfo(name);
|
||||||
|
if (moduleInfo && moduleInfo.path) {
|
||||||
|
var relPath = path.relative(__dirname, moduleInfo.path);
|
||||||
|
return require(relPath);
|
||||||
|
} else {
|
||||||
|
var err = new Error(`Cannot find module '${name}'`);
|
||||||
|
err.code = "MODULE_NOT_FOUND";
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createNodeApi(node) {
|
function createNodeApi(node) {
|
||||||
var red = {
|
var red = {
|
||||||
@ -73,6 +84,7 @@ function createNodeApi(node) {
|
|||||||
events: runtime.events,
|
events: runtime.events,
|
||||||
util: runtime.util,
|
util: runtime.util,
|
||||||
version: runtime.version,
|
version: runtime.version,
|
||||||
|
require: requireModule,
|
||||||
comms: {
|
comms: {
|
||||||
publish: function(topic,data,retain) {
|
publish: function(topic,data,retain) {
|
||||||
runtime.events.emit("comms",{
|
runtime.events.emit("comms",{
|
||||||
|
@ -88,7 +88,7 @@ function getLocalNodeFiles(dir) {
|
|||||||
try {
|
try {
|
||||||
files = fs.readdirSync(dir);
|
files = fs.readdirSync(dir);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
return result;
|
return {files: [], icons: []};
|
||||||
}
|
}
|
||||||
files.sort();
|
files.sort();
|
||||||
files.forEach(function(fn) {
|
files.forEach(function(fn) {
|
||||||
@ -296,6 +296,7 @@ function getNodeFiles(disableNodePathScan) {
|
|||||||
nodeList[moduleFile.package.name] = {
|
nodeList[moduleFile.package.name] = {
|
||||||
name: moduleFile.package.name,
|
name: moduleFile.package.name,
|
||||||
version: moduleFile.package.version,
|
version: moduleFile.package.version,
|
||||||
|
path: moduleFile.dir,
|
||||||
local: moduleFile.local||false,
|
local: moduleFile.local||false,
|
||||||
nodes: {},
|
nodes: {},
|
||||||
icons: nodeModuleFiles.icons,
|
icons: nodeModuleFiles.icons,
|
||||||
|
@ -339,6 +339,7 @@ function getModuleInfo(module) {
|
|||||||
name: module,
|
name: module,
|
||||||
version: moduleConfigs[module].version,
|
version: moduleConfigs[module].version,
|
||||||
local: moduleConfigs[module].local,
|
local: moduleConfigs[module].local,
|
||||||
|
path: moduleConfigs[module].path,
|
||||||
nodes: []
|
nodes: []
|
||||||
};
|
};
|
||||||
for (var i = 0; i < nodes.length; ++i) {
|
for (var i = 0; i < nodes.length; ++i) {
|
||||||
@ -560,30 +561,6 @@ var icon_paths = {
|
|||||||
var iconCache = {};
|
var iconCache = {};
|
||||||
var defaultIcon = path.resolve(__dirname + '/../../public/icons/arrow-in.png');
|
var defaultIcon = path.resolve(__dirname + '/../../public/icons/arrow-in.png');
|
||||||
|
|
||||||
function nodeIconDir(dir) {
|
|
||||||
icon_paths[dir.name] = icon_paths[dir.name] || [];
|
|
||||||
icon_paths[dir.name].push(path.resolve(dir.path));
|
|
||||||
|
|
||||||
if (dir.icons) {
|
|
||||||
if (!moduleConfigs[dir.name]) {
|
|
||||||
moduleConfigs[dir.name] = {
|
|
||||||
name: dir.name,
|
|
||||||
nodes: {},
|
|
||||||
icons: []
|
|
||||||
};
|
|
||||||
}
|
|
||||||
var module = moduleConfigs[dir.name];
|
|
||||||
if (module.icons === undefined) {
|
|
||||||
module.icons = [];
|
|
||||||
}
|
|
||||||
dir.icons.forEach(function(icon) {
|
|
||||||
if (module.icons.indexOf(icon) === -1) {
|
|
||||||
module.icons.push(icon);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNodeIconPath(module,icon) {
|
function getNodeIconPath(module,icon) {
|
||||||
if (/\.\./.test(icon)) {
|
if (/\.\./.test(icon)) {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
@ -624,7 +601,6 @@ function getNodeIcons() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return iconList;
|
return iconList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,8 @@ function diffNodes(oldNode,newNode) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var EnvVarPropertyRE = /^\$\((\S+)\)$/;
|
var EnvVarPropertyRE_old = /^\$\((\S+)\)$/;
|
||||||
|
var EnvVarPropertyRE = /^\${(\S+)}$/;
|
||||||
|
|
||||||
function mapEnvVarProperties(obj,prop) {
|
function mapEnvVarProperties(obj,prop) {
|
||||||
if (Buffer.isBuffer(obj[prop])) {
|
if (Buffer.isBuffer(obj[prop])) {
|
||||||
@ -47,11 +48,9 @@ function mapEnvVarProperties(obj,prop) {
|
|||||||
mapEnvVarProperties(obj[prop],i);
|
mapEnvVarProperties(obj[prop],i);
|
||||||
}
|
}
|
||||||
} else if (typeof obj[prop] === 'string') {
|
} else if (typeof obj[prop] === 'string') {
|
||||||
var m;
|
if (obj[prop][0] === "$" && (EnvVarPropertyRE_old.test(obj[prop]) || EnvVarPropertyRE.test(obj[prop])) ) {
|
||||||
if ( (m = EnvVarPropertyRE.exec(obj[prop])) !== null) {
|
var envVar = obj[prop].substring(2,obj[prop].length-1);
|
||||||
if (process.env.hasOwnProperty(m[1])) {
|
obj[prop] = process.env.hasOwnProperty(envVar)?process.env[envVar]:obj[prop];
|
||||||
obj[prop] = process.env[m[1]];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (var p in obj[prop]) {
|
for (var p in obj[prop]) {
|
||||||
|
@ -73,7 +73,8 @@ var localfilesystem = {
|
|||||||
var defaultPackage = {
|
var defaultPackage = {
|
||||||
"name": "node-red-project",
|
"name": "node-red-project",
|
||||||
"description": "A Node-RED Project",
|
"description": "A Node-RED Project",
|
||||||
"version": "0.0.1"
|
"version": "0.0.1",
|
||||||
|
"private": true
|
||||||
};
|
};
|
||||||
return util.writeFile(packageFile,JSON.stringify(defaultPackage,"",4));
|
return util.writeFile(packageFile,JSON.stringify(defaultPackage,"",4));
|
||||||
}
|
}
|
||||||
|
@ -303,6 +303,23 @@ function setMessageProperty(msg,prop,value,createMissing) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function evaluteEnvProperty(value) {
|
||||||
|
if (/^\${[^}]+}$/.test(value)) {
|
||||||
|
// ${ENV_VAR}
|
||||||
|
value = value.substring(2,value.length-1);
|
||||||
|
value = process.env.hasOwnProperty(value)?process.env[value]:""
|
||||||
|
} else if (!/\${\S+}/.test(value)) {
|
||||||
|
// ENV_VAR
|
||||||
|
value = process.env.hasOwnProperty(value)?process.env[value]:""
|
||||||
|
} else {
|
||||||
|
// FOO${ENV_VAR}BAR
|
||||||
|
value = value.replace(/\${([^}]+)}/g, function(match, v) {
|
||||||
|
return process.env.hasOwnProperty(v)?process.env[v]:""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
function evaluateNodeProperty(value, type, node, msg) {
|
function evaluateNodeProperty(value, type, node, msg) {
|
||||||
if (type === 'str') {
|
if (type === 'str') {
|
||||||
return ""+value;
|
return ""+value;
|
||||||
@ -328,6 +345,8 @@ function evaluateNodeProperty(value, type, node, msg) {
|
|||||||
} else if (type === 'jsonata') {
|
} else if (type === 'jsonata') {
|
||||||
var expr = prepareJSONataExpression(value,node);
|
var expr = prepareJSONataExpression(value,node);
|
||||||
return evaluateJSONataExpression(expr,msg);
|
return evaluateJSONataExpression(expr,msg);
|
||||||
|
} else if (type === 'env') {
|
||||||
|
return evaluteEnvProperty(value);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -340,6 +359,9 @@ function prepareJSONataExpression(value,node) {
|
|||||||
expr.assign('globalContext',function(val) {
|
expr.assign('globalContext',function(val) {
|
||||||
return node.context().global.get(val);
|
return node.context().global.get(val);
|
||||||
});
|
});
|
||||||
|
expr.assign('env', function(val) {
|
||||||
|
return process.env[val];
|
||||||
|
})
|
||||||
expr.registerFunction('clone', cloneMessage, '<(oa)-:o>');
|
expr.registerFunction('clone', cloneMessage, '<(oa)-:o>');
|
||||||
expr._legacyMode = /(^|[^a-zA-Z0-9_'"])msg([^a-zA-Z0-9_'"]|$)/.test(value);
|
expr._legacyMode = /(^|[^a-zA-Z0-9_'"])msg([^a-zA-Z0-9_'"]|$)/.test(value);
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -409,6 +409,33 @@ describe('change Node', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('env var', function() {
|
||||||
|
before(function() {
|
||||||
|
process.env.NR_TEST_A = 'foo';
|
||||||
|
})
|
||||||
|
after(function() {
|
||||||
|
delete process.env.NR_TEST_A;
|
||||||
|
})
|
||||||
|
it('sets the value using env property', function(done) {
|
||||||
|
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","pt":"msg","to":"NR_TEST_A","tot":"env"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||||
|
{id:"helperNode1", type:"helper", wires:[]}];
|
||||||
|
helper.load(changeNode, flow, function() {
|
||||||
|
var changeNode1 = helper.getNode("changeNode1");
|
||||||
|
var helperNode1 = helper.getNode("helperNode1");
|
||||||
|
helperNode1.on("input", function(msg) {
|
||||||
|
try {
|
||||||
|
msg.payload.should.equal("foo");
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
changeNode1.receive({payload:"123",topic:"ABC"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it('changes the value using jsonata', function(done) {
|
it('changes the value using jsonata', function(done) {
|
||||||
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$length(payload)","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]]},
|
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"set","p":"payload","to":"$length(payload)","tot":"jsonata"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||||
{id:"helperNode1", type:"helper", wires:[]}];
|
{id:"helperNode1", type:"helper", wires:[]}];
|
||||||
@ -872,6 +899,33 @@ describe('change Node', function() {
|
|||||||
changeNode1.receive({payload:""});
|
changeNode1.receive({payload:""});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('env var', function() {
|
||||||
|
before(function() {
|
||||||
|
process.env.NR_TEST_A = 'foo';
|
||||||
|
})
|
||||||
|
after(function() {
|
||||||
|
delete process.env.NR_TEST_A;
|
||||||
|
})
|
||||||
|
it('changes the value using env property', function(done) {
|
||||||
|
var flow = [{"id":"changeNode1","type":"change",rules:[{"t":"change","p":"payload","from":"topic","to":"NR_TEST_A","fromt":"msg","tot":"env"}],"name":"changeNode","wires":[["helperNode1"]]},
|
||||||
|
{id:"helperNode1", type:"helper", wires:[]}];
|
||||||
|
helper.load(changeNode, flow, function() {
|
||||||
|
var changeNode1 = helper.getNode("changeNode1");
|
||||||
|
var helperNode1 = helper.getNode("helperNode1");
|
||||||
|
helperNode1.on("input", function(msg) {
|
||||||
|
try {
|
||||||
|
msg.payload.should.equal("abcfooabc");
|
||||||
|
done();
|
||||||
|
} catch(err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
changeNode1.receive({payload:"abcABCabc",topic:"ABC"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("#delete", function() {
|
describe("#delete", function() {
|
||||||
|
@ -35,10 +35,17 @@ describe('flows/util', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#mapEnvVarProperties',function() {
|
describe('#mapEnvVarProperties',function() {
|
||||||
it('handles ENV substitutions in an object', function() {
|
before(function() {
|
||||||
process.env.foo1 = "bar1";
|
process.env.foo1 = "bar1";
|
||||||
process.env.foo2 = "bar2";
|
process.env.foo2 = "bar2";
|
||||||
process.env.foo3 = "bar3";
|
process.env.foo3 = "bar3";
|
||||||
|
})
|
||||||
|
after(function() {
|
||||||
|
delete process.env.foo1;
|
||||||
|
delete process.env.foo2;
|
||||||
|
delete process.env.foo3;
|
||||||
|
})
|
||||||
|
it('handles ENV substitutions in an object - $()', function() {
|
||||||
var foo = {a:"$(foo1)",b:"$(foo2)",c:{d:"$(foo3)"}};
|
var foo = {a:"$(foo1)",b:"$(foo2)",c:{d:"$(foo3)"}};
|
||||||
for (var p in foo) {
|
for (var p in foo) {
|
||||||
if (foo.hasOwnProperty(p)) {
|
if (foo.hasOwnProperty(p)) {
|
||||||
@ -47,6 +54,15 @@ describe('flows/util', function() {
|
|||||||
}
|
}
|
||||||
foo.should.eql({ a: 'bar1', b: 'bar2', c: { d: 'bar3' } } );
|
foo.should.eql({ a: 'bar1', b: 'bar2', c: { d: 'bar3' } } );
|
||||||
});
|
});
|
||||||
|
it('handles ENV substitutions in an object - ${}', function() {
|
||||||
|
var foo = {a:"${foo1}",b:"${foo2}",c:{d:"${foo3}"}};
|
||||||
|
for (var p in foo) {
|
||||||
|
if (foo.hasOwnProperty(p)) {
|
||||||
|
flowUtil.mapEnvVarProperties(foo,p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.should.eql({ a: 'bar1', b: 'bar2', c: { d: 'bar3' } } );
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#diffNodes',function() {
|
describe('#diffNodes',function() {
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 393 B |
3
test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/icons/arrow-in.png
generated
vendored
Normal file
3
test/red/runtime/nodes/resources/local/TestNodeModule/node_modules/TestNodeModule/icons/arrow-in.png
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This file exists just to ensure the 'icons' directory is in the repository.
|
||||||
|
TODO: a future test needs to ensure the right icon files are loaded - this
|
||||||
|
directory can be used for that
|
@ -307,6 +307,38 @@ describe("red/util", function() {
|
|||||||
},{});
|
},{});
|
||||||
result.should.eql("123");
|
result.should.eql("123");
|
||||||
});
|
});
|
||||||
|
describe('environment variable', function() {
|
||||||
|
before(function() {
|
||||||
|
process.env.NR_TEST_A = "foo";
|
||||||
|
process.env.NR_TEST_B = "${NR_TEST_A}";
|
||||||
|
})
|
||||||
|
after(function() {
|
||||||
|
delete process.env.NR_TEST_A;
|
||||||
|
delete process.env.NR_TEST_B;
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns an environment variable - NR_TEST_A', function() {
|
||||||
|
var result = util.evaluateNodeProperty('NR_TEST_A','env');
|
||||||
|
result.should.eql('foo');
|
||||||
|
});
|
||||||
|
it('returns an environment variable - ${NR_TEST_A}', function() {
|
||||||
|
var result = util.evaluateNodeProperty('${NR_TEST_A}','env');
|
||||||
|
result.should.eql('foo');
|
||||||
|
});
|
||||||
|
it('returns an environment variable - ${NR_TEST_A', function() {
|
||||||
|
var result = util.evaluateNodeProperty('${NR_TEST_A','env');
|
||||||
|
result.should.eql('');
|
||||||
|
});
|
||||||
|
it('returns an environment variable - foo${NR_TEST_A}bar', function() {
|
||||||
|
var result = util.evaluateNodeProperty('123${NR_TEST_A}456','env');
|
||||||
|
result.should.eql('123foo456');
|
||||||
|
});
|
||||||
|
it('returns an environment variable - foo${NR_TEST_B}bar', function() {
|
||||||
|
var result = util.evaluateNodeProperty('123${NR_TEST_B}456','env');
|
||||||
|
result.should.eql('123${NR_TEST_A}456');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('normalisePropertyExpression', function() {
|
describe('normalisePropertyExpression', function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user