mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
merge 0.19
This commit is contained in:
commit
467411c6c3
@ -144,6 +144,7 @@ module.exports = function(grunt) {
|
||||
"editor/js/ui/keyboard.js",
|
||||
"editor/js/ui/workspaces.js",
|
||||
"editor/js/ui/view.js",
|
||||
"editor/js/ui/view-navigator.js",
|
||||
"editor/js/ui/sidebar.js",
|
||||
"editor/js/ui/palette.js",
|
||||
"editor/js/ui/tab-info.js",
|
||||
|
BIN
editor/icons/file-in.png
Normal file
BIN
editor/icons/file-in.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 542 B |
BIN
editor/icons/file-out.png
Normal file
BIN
editor/icons/file-out.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 503 B |
@ -133,7 +133,7 @@ RED.nodes = (function() {
|
||||
registerNodeType: function(nt,def) {
|
||||
nodeDefinitions[nt] = def;
|
||||
def.type = nt;
|
||||
if (def.category != "subflows") {
|
||||
if (nt.substring(0,8) != "subflow:") {
|
||||
def.set = nodeSets[typeToId[nt]];
|
||||
nodeSets[typeToId[nt]].added = true;
|
||||
nodeSets[typeToId[nt]].enabled = true;
|
||||
@ -356,7 +356,7 @@ RED.nodes = (function() {
|
||||
defaults:{name:{value:""}},
|
||||
info: sf.info,
|
||||
icon: function() { return sf.icon||"subflow.png" },
|
||||
category: "subflows",
|
||||
category: sf.category || "subflows",
|
||||
inputs: sf.in.length,
|
||||
outputs: sf.out.length,
|
||||
color: "#da9",
|
||||
@ -519,6 +519,7 @@ RED.nodes = (function() {
|
||||
node.type = n.type;
|
||||
node.name = n.name;
|
||||
node.info = n.info;
|
||||
node.category = n.category;
|
||||
node.in = [];
|
||||
node.out = [];
|
||||
|
||||
|
@ -170,8 +170,8 @@ RED.tabs = (function() {
|
||||
ul.children().css({"transition": "width 100ms"});
|
||||
link.parent().addClass("active");
|
||||
var parentId = link.parent().attr('id');
|
||||
wrapper.find(".red-ui-tab-link-button").removeClass("active");
|
||||
$("#"+parentId+"-link-button").addClass("active");
|
||||
wrapper.find(".red-ui-tab-link-button").removeClass("active selected");
|
||||
$("#"+parentId+"-link-button").addClass("active selected");
|
||||
if (options.scrollable) {
|
||||
var pos = link.parent().position().left;
|
||||
if (pos-21 < 0) {
|
||||
|
@ -108,17 +108,6 @@ RED.editor = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.icon) {
|
||||
var iconPath = RED.utils.separateIconPath(node.icon);
|
||||
if (!iconPath.module) {
|
||||
return isValid;
|
||||
}
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
var iconFileList = iconSets[iconPath.module];
|
||||
if (!iconFileList || iconFileList.indexOf(iconPath.file) === -1) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
@ -170,27 +159,6 @@ RED.editor = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
validateIcon(node);
|
||||
}
|
||||
|
||||
function validateIcon(node) {
|
||||
if (node._def.hasOwnProperty("defaults") && !node._def.defaults.hasOwnProperty("icon") && node.icon) {
|
||||
var iconPath = RED.utils.separateIconPath(node.icon);
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
var iconFileList = iconSets[iconPath.module];
|
||||
var iconModule = $("#node-settings-icon-module");
|
||||
var iconFile = $("#node-settings-icon-file");
|
||||
if (!iconFileList) {
|
||||
iconModule.addClass("input-error");
|
||||
iconFile.removeClass("input-error");
|
||||
} else if (iconFileList.indexOf(iconPath.file) === -1) {
|
||||
iconModule.removeClass("input-error");
|
||||
iconFile.addClass("input-error");
|
||||
} else {
|
||||
iconModule.removeClass("input-error");
|
||||
iconFile.removeClass("input-error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function validateNodeEditorProperty(node,defaults,property,prefix) {
|
||||
@ -711,6 +679,97 @@ RED.editor = (function() {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function showIconPicker(container, node, iconPath, done) {
|
||||
var containerPos = container.offset();
|
||||
var pickerBackground = $('<div>').css({
|
||||
position: "absolute",top:0,bottom:0,left:0,right:0,zIndex:20
|
||||
}).appendTo("body");
|
||||
|
||||
var top = containerPos.top - 30;
|
||||
|
||||
if (top+280 > $( window ).height()) {
|
||||
top = $( window ).height() - 280;
|
||||
}
|
||||
var picker = $('<div class="red-ui-icon-picker">').css({
|
||||
top: top+"px",
|
||||
left: containerPos.left+"px",
|
||||
}).appendTo("body");
|
||||
|
||||
var hide = function() {
|
||||
pickerBackground.remove();
|
||||
picker.remove();
|
||||
RED.keyboard.remove("escape");
|
||||
}
|
||||
RED.keyboard.add("*","escape",function(){hide()});
|
||||
pickerBackground.on("mousedown", hide);
|
||||
|
||||
var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(picker);
|
||||
searchInput = $('<input type="text">').attr("placeholder","Search icons").appendTo(searchDiv).searchBox({
|
||||
delay: 50,
|
||||
change: function() {
|
||||
var searchTerm = $(this).val().trim();
|
||||
if (searchTerm === "") {
|
||||
iconList.find(".red-ui-icon-list-module").show();
|
||||
iconList.find(".red-ui-icon-list-icon").show();
|
||||
} else {
|
||||
iconList.find(".red-ui-icon-list-module").hide();
|
||||
iconList.find(".red-ui-icon-list-icon").each(function(i,n) {
|
||||
if ($(n).data('icon').indexOf(searchTerm) === -1) {
|
||||
$(n).hide();
|
||||
} else {
|
||||
$(n).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var row = $('<div>').appendTo(picker);
|
||||
var iconList = $('<div class="red-ui-icon-list">').appendTo(picker);
|
||||
var metaRow = $('<div class="red-ui-icon-meta"></div>').appendTo(picker);
|
||||
var summary = $('<span>').appendTo(metaRow);
|
||||
var resetButton = $('<button class="editor-button editor-button-small">use default</button>').appendTo(metaRow).click(function(e) {
|
||||
e.preventDefault();
|
||||
hide();
|
||||
done(null);
|
||||
});
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
Object.keys(iconSets).forEach(function(moduleName) {
|
||||
var icons = iconSets[moduleName];
|
||||
if (icons.length > 0) {
|
||||
// selectIconModule.append($("<option></option>").val(moduleName).text(moduleName));
|
||||
var header = $('<div class="red-ui-icon-list-module"></div>').text(moduleName).appendTo(iconList);
|
||||
$('<i class="fa fa-cube"></i>').prependTo(header);
|
||||
icons.forEach(function(icon) {
|
||||
var iconDiv = $('<div>',{class:"red-ui-icon-list-icon"}).appendTo(iconList);
|
||||
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconDiv);
|
||||
var colour = node._def.color;
|
||||
var icon_url = "icons/"+moduleName+"/"+icon;
|
||||
iconDiv.data('icon',icon_url)
|
||||
nodeDiv.css('backgroundColor',colour);
|
||||
var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
||||
$('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer);
|
||||
|
||||
if (iconPath.module === moduleName && iconPath.file === icon) {
|
||||
iconDiv.addClass("selected");
|
||||
}
|
||||
iconDiv.on("mouseover", function() {
|
||||
summary.text(icon);
|
||||
})
|
||||
iconDiv.on("mouseout", function() {
|
||||
summary.html(" ");
|
||||
})
|
||||
iconDiv.click(function() {
|
||||
hide();
|
||||
done(moduleName+"/"+icon);
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
picker.slideDown(100);
|
||||
searchInput.focus();
|
||||
}
|
||||
|
||||
function buildLabelForm(container,node) {
|
||||
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
||||
|
||||
@ -748,81 +807,36 @@ RED.editor = (function() {
|
||||
}
|
||||
|
||||
if ((!node._def.defaults || !node._def.defaults.hasOwnProperty("icon"))) {
|
||||
$('<div class="form-row"><div id="node-settings-icon"></div></div>').appendTo(dialogForm);
|
||||
var iconDiv = $("#node-settings-icon");
|
||||
$('<label data-i18n="editor.settingIcon">').appendTo(iconDiv);
|
||||
var iconForm = $('<div>',{class:"node-label-form-row"});
|
||||
iconForm.appendTo(iconDiv);
|
||||
$('<label>').appendTo(iconForm);
|
||||
$('<hr>').appendTo(dialogForm);
|
||||
var iconRow = $('<div class="form-row"></div>').appendTo(dialogForm);
|
||||
$('<label style="width: 50px" data-i18n="editor.settingIcon">').appendTo(iconRow);
|
||||
|
||||
var selectIconModule = $('<select id="node-settings-icon-module"><option value=""></option></select>').appendTo(iconForm);
|
||||
var iconButton = $('<button class="editor-button">').appendTo(iconRow);
|
||||
|
||||
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconButton);
|
||||
var colour = node._def.color;
|
||||
var icon_url = RED.utils.getNodeIcon(node._def,node);
|
||||
nodeDiv.css('backgroundColor',colour);
|
||||
var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
||||
var iconDiv = $('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer);
|
||||
|
||||
iconButton.click(function(e) {
|
||||
e.preventDefault();
|
||||
var iconPath;
|
||||
if (node.icon) {
|
||||
iconPath = RED.utils.separateIconPath(node.icon);
|
||||
var icon = $("#node-settings-icon").text()||"";
|
||||
if (icon) {
|
||||
iconPath = RED.utils.separateIconPath(icon);
|
||||
} else {
|
||||
iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||
}
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
Object.keys(iconSets).forEach(function(moduleName) {
|
||||
selectIconModule.append($("<option></option>").val(moduleName).text(moduleName));
|
||||
showIconPicker(iconRow,node,iconPath,function(newIcon) {
|
||||
$("#node-settings-icon").text(newIcon||"");
|
||||
var icon_url = RED.utils.getNodeIcon(node._def,{type:node.type,icon:newIcon});
|
||||
iconDiv.css("backgroundImage","url("+icon_url+")");
|
||||
});
|
||||
if (iconPath.module && !iconSets[iconPath.module]) {
|
||||
selectIconModule.append($("<option disabled></option>").val(iconPath.module).text(iconPath.module));
|
||||
})
|
||||
$('<div class="uneditable-input" id="node-settings-icon">').text(node.icon).appendTo(iconRow);
|
||||
}
|
||||
selectIconModule.val(iconPath.module);
|
||||
var iconModuleHidden = $('<input type="hidden" id="node-settings-icon-module-hidden"></input>').appendTo(iconForm);
|
||||
iconModuleHidden.val(iconPath.module);
|
||||
|
||||
var selectIconFile = $('<select id="node-settings-icon-file"><option value=""></option></select>').appendTo(iconForm);
|
||||
selectIconModule.change(function() {
|
||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, true);
|
||||
});
|
||||
var iconFileHidden = $('<input type="hidden" id="node-settings-icon-file-hidden"></input>').appendTo(iconForm);
|
||||
iconFileHidden.val(iconPath.file);
|
||||
selectIconFile.change(function() {
|
||||
selectIconFile.removeClass("input-error");
|
||||
var fileName = selectIconFile.val();
|
||||
iconFileHidden.val(fileName);
|
||||
});
|
||||
var clear = $('<button class="editor-button editor-button-small"><i class="fa fa-times"></i></button>').appendTo(iconForm);
|
||||
clear.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||
selectIconModule.val(iconPath.module);
|
||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, true);
|
||||
selectIconFile.removeClass("input-error");
|
||||
selectIconFile.val(iconPath.file);
|
||||
iconFileHidden.val(iconPath.file);
|
||||
});
|
||||
|
||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, false);
|
||||
var iconFileList = iconSets[selectIconModule.val()];
|
||||
if (!iconFileList || iconFileList.indexOf(iconPath.file) === -1) {
|
||||
selectIconFile.append($("<option disabled></option>").val(iconPath.file).text(iconPath.file));
|
||||
}
|
||||
selectIconFile.val(iconPath.file);
|
||||
}
|
||||
}
|
||||
|
||||
function moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, updateIconFile) {
|
||||
selectIconFile.children().remove();
|
||||
var moduleName = selectIconModule.val();
|
||||
if (moduleName !== null) {
|
||||
iconModuleHidden.val(moduleName);
|
||||
}
|
||||
var iconFileList = iconSets[moduleName];
|
||||
if (iconFileList) {
|
||||
iconFileList.forEach(function(fileName) {
|
||||
if (updateIconFile) {
|
||||
updateIconFile = false;
|
||||
iconFileHidden.val(fileName);
|
||||
}
|
||||
selectIconFile.append($("<option></option>").val(fileName).text(fileName));
|
||||
});
|
||||
}
|
||||
selectIconFile.prop("disabled", !iconFileList);
|
||||
selectIconFile.removeClass("input-error");
|
||||
selectIconModule.removeClass("input-error");
|
||||
}
|
||||
|
||||
function updateLabels(editing_node, changes, outputMap) {
|
||||
@ -1086,9 +1100,7 @@ RED.editor = (function() {
|
||||
}
|
||||
|
||||
if (!editing_node._def.defaults || !editing_node._def.defaults.hasOwnProperty("icon")) {
|
||||
var iconModule = $("#node-settings-icon-module-hidden").val();
|
||||
var iconFile = $("#node-settings-icon-file-hidden").val();
|
||||
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
|
||||
var icon = $("#node-settings-icon").text()||""
|
||||
if (!isDefaultIcon) {
|
||||
if (icon !== editing_node.icon) {
|
||||
changes.icon = editing_node.icon;
|
||||
@ -1692,15 +1704,28 @@ RED.editor = (function() {
|
||||
if (updateLabels(editing_node, changes, null)) {
|
||||
changed = true;
|
||||
}
|
||||
var iconModule = $("#node-settings-icon-module-hidden").val();
|
||||
var iconFile = $("#node-settings-icon-file-hidden").val();
|
||||
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
|
||||
var icon = $("#node-settings-icon").text()||"";
|
||||
if ((editing_node.icon === undefined && icon !== "node-red/subflow.png") ||
|
||||
(editing_node.icon !== undefined && editing_node.icon !== icon)) {
|
||||
changes.icon = editing_node.icon;
|
||||
editing_node.icon = icon;
|
||||
changed = true;
|
||||
}
|
||||
var newCategory = $("#subflow-input-category").val().trim();
|
||||
if (newCategory === "_custom_") {
|
||||
newCategory = $("#subflow-input-custom-category").val().trim();
|
||||
if (newCategory === "") {
|
||||
newCategory = editing_node.category;
|
||||
}
|
||||
}
|
||||
if (newCategory === 'subflows') {
|
||||
newCategory = '';
|
||||
}
|
||||
if (newCategory != editing_node.category) {
|
||||
changes['category'] = editing_node.category;
|
||||
editing_node.category = newCategory;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
RED.palette.refresh();
|
||||
|
||||
@ -1773,8 +1798,6 @@ RED.editor = (function() {
|
||||
});
|
||||
portLabels.content.addClass("editor-tray-content");
|
||||
|
||||
|
||||
|
||||
if (editing_node) {
|
||||
RED.sidebar.info.refresh(editing_node);
|
||||
}
|
||||
@ -1787,6 +1810,33 @@ RED.editor = (function() {
|
||||
|
||||
$("#subflow-input-name").val(subflow.name);
|
||||
RED.text.bidi.prepareInput($("#subflow-input-name"));
|
||||
|
||||
$("#subflow-input-category").empty();
|
||||
var categories = RED.palette.getCategories();
|
||||
categories.sort(function(A,B) {
|
||||
return A.label.localeCompare(B.label);
|
||||
})
|
||||
categories.forEach(function(cat) {
|
||||
$("#subflow-input-category").append($("<option></option>").val(cat.id).text(cat.label));
|
||||
})
|
||||
$("#subflow-input-category").append($("<option></option>").attr('disabled',true).text("---"));
|
||||
$("#subflow-input-category").append($("<option></option>").val("_custom_").text(RED._("palette.addCategory")));
|
||||
|
||||
|
||||
$("#subflow-input-category").change(function() {
|
||||
var val = $(this).val();
|
||||
if (val === "_custom_") {
|
||||
$("#subflow-input-category").width(120);
|
||||
$("#subflow-input-custom-category").show();
|
||||
} else {
|
||||
$("#subflow-input-category").width(250);
|
||||
$("#subflow-input-custom-category").hide();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
$("#subflow-input-category").val(subflow.category||"subflows");
|
||||
|
||||
subflowEditor.getSession().setValue(subflow.info||"",-1);
|
||||
var userCount = 0;
|
||||
var subflowType = "subflow:"+editing_node.id;
|
||||
@ -1799,7 +1849,6 @@ RED.editor = (function() {
|
||||
$("#subflow-dialog-user-count").text(RED._("subflow.subflowInstances", {count:userCount})).show();
|
||||
|
||||
buildLabelForm(portLabels.content,subflow);
|
||||
validateIcon(subflow);
|
||||
trayBody.i18n();
|
||||
},
|
||||
close: function() {
|
||||
|
@ -21,7 +21,18 @@ RED.palette = (function() {
|
||||
|
||||
var categoryContainers = {};
|
||||
|
||||
function createCategoryContainer(category, label) {
|
||||
|
||||
function createCategory(originalCategory,rootCategory,category,ns) {
|
||||
if ($("#palette-base-category-"+rootCategory).length === 0) {
|
||||
createCategoryContainer(originalCategory,rootCategory, ns+":palette.label."+rootCategory);
|
||||
}
|
||||
$("#palette-container-"+rootCategory).show();
|
||||
if ($("#palette-"+category).length === 0) {
|
||||
$("#palette-base-category-"+rootCategory).append('<div id="palette-'+category+'"></div>');
|
||||
}
|
||||
}
|
||||
function createCategoryContainer(originalCategory,category, labelId) {
|
||||
var label = RED._(labelId, {defaultValue:category});
|
||||
label = (label || category).replace(/_/g, " ");
|
||||
var catDiv = $('<div id="palette-container-'+category+'" class="palette-category palette-close hide">'+
|
||||
'<div id="palette-header-'+category+'" class="palette-header"><i class="expanded fa fa-angle-down"></i><span>'+label+'</span></div>'+
|
||||
@ -31,7 +42,8 @@ RED.palette = (function() {
|
||||
'<div id="palette-'+category+'-function"></div>'+
|
||||
'</div>'+
|
||||
'</div>').appendTo("#palette-container");
|
||||
|
||||
catDiv.data('category',originalCategory);
|
||||
catDiv.data('label',label);
|
||||
categoryContainers[category] = {
|
||||
container: catDiv,
|
||||
close: function() {
|
||||
@ -133,6 +145,7 @@ RED.palette = (function() {
|
||||
}
|
||||
if (exclusion.indexOf(def.category)===-1) {
|
||||
|
||||
var originalCategory = def.category;
|
||||
var category = def.category.replace(/ /g,"_");
|
||||
var rootCategory = category.split("-")[0];
|
||||
|
||||
@ -153,7 +166,6 @@ RED.palette = (function() {
|
||||
|
||||
d.className="palette_node";
|
||||
|
||||
|
||||
if (def.icon) {
|
||||
var icon_url = RED.utils.getNodeIcon(def);
|
||||
var iconContainer = $('<div/>',{class:"palette_icon_container"+(def.align=="right"?" palette_icon_container_right":"")}).appendTo(d);
|
||||
@ -174,21 +186,12 @@ RED.palette = (function() {
|
||||
d.appendChild(portIn);
|
||||
}
|
||||
|
||||
if ($("#palette-base-category-"+rootCategory).length === 0) {
|
||||
if(coreCategories.indexOf(rootCategory) !== -1){
|
||||
createCategoryContainer(rootCategory, RED._("node-red:palette.label."+rootCategory, {defaultValue:rootCategory}));
|
||||
} else {
|
||||
var ns = def.set.id;
|
||||
createCategoryContainer(rootCategory, RED._(ns+":palette.label."+rootCategory, {defaultValue:rootCategory}));
|
||||
}
|
||||
}
|
||||
$("#palette-container-"+rootCategory).show();
|
||||
|
||||
if ($("#palette-"+category).length === 0) {
|
||||
$("#palette-base-category-"+rootCategory).append('<div id="palette-'+category+'"></div>');
|
||||
}
|
||||
createCategory(def.category,rootCategory,category,(coreCategories.indexOf(rootCategory) !== -1)?"node-red":def.set.id);
|
||||
|
||||
$("#palette-"+category).append(d);
|
||||
|
||||
$(d).data('category',rootCategory);
|
||||
|
||||
d.onmousedown = function(e) { e.preventDefault(); };
|
||||
|
||||
var popover = RED.popover.create({
|
||||
@ -308,7 +311,7 @@ RED.palette = (function() {
|
||||
});
|
||||
|
||||
var nodeInfo = null;
|
||||
if (def.category == "subflows") {
|
||||
if (nt.indexOf("subflow:") === 0) {
|
||||
$(d).dblclick(function(e) {
|
||||
RED.workspaces.show(nt.substring(8));
|
||||
e.preventDefault();
|
||||
@ -382,6 +385,31 @@ RED.palette = (function() {
|
||||
}
|
||||
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,marked(sf.info||""));
|
||||
setIcon(paletteNode,sf);
|
||||
|
||||
var currentCategory = paletteNode.data('category');
|
||||
var newCategory = (sf.category||"subflows");
|
||||
if (currentCategory !== newCategory) {
|
||||
var category = newCategory.replace(/ /g,"_");
|
||||
createCategory(newCategory,category,category,"node-red");
|
||||
|
||||
var currentCategoryNode = paletteNode.closest(".palette-category");
|
||||
var newCategoryNode = $("#palette-"+category);
|
||||
newCategoryNode.append(paletteNode);
|
||||
if (newCategoryNode.find(".palette_node").length === 1) {
|
||||
categoryContainers[category].open();
|
||||
}
|
||||
|
||||
paletteNode.data('category',newCategory);
|
||||
if (currentCategoryNode.find(".palette_node").length === 0) {
|
||||
if (currentCategoryNode.find("i").hasClass("expanded")) {
|
||||
currentCategoryNode.find(".palette-content").slideToggle();
|
||||
currentCategoryNode.find("i").toggleClass("expanded");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -471,7 +499,7 @@ RED.palette = (function() {
|
||||
categoryList = coreCategories
|
||||
}
|
||||
categoryList.forEach(function(category){
|
||||
createCategoryContainer(category, RED._("palette.label."+category,{defaultValue:category}));
|
||||
createCategoryContainer(category, category, "palette.label."+category);
|
||||
});
|
||||
|
||||
$("#palette-collapse-all").on("click", function(e) {
|
||||
@ -491,13 +519,20 @@ RED.palette = (function() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getCategories() {
|
||||
var categories = [];
|
||||
$("#palette-container .palette-category").each(function(i,d) {
|
||||
categories.push({id:$(d).data('category'),label:$(d).data('label')});
|
||||
})
|
||||
return categories;
|
||||
}
|
||||
return {
|
||||
init: init,
|
||||
add:addNodeType,
|
||||
remove:removeNodeType,
|
||||
hide:hideNodeType,
|
||||
show:showNodeType,
|
||||
refresh:refreshNodeTypes
|
||||
refresh:refreshNodeTypes,
|
||||
getCategories: getCategories
|
||||
};
|
||||
})();
|
||||
|
@ -49,7 +49,7 @@ RED.projects.settings = (function() {
|
||||
var tabContainer;
|
||||
|
||||
var trayOptions = {
|
||||
title: "Project Settings",// RED._("menu.label.userSettings"),, // TODO: nls
|
||||
title: RED._("menu.label.userSettings"),
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-ok",
|
||||
@ -173,14 +173,14 @@ RED.projects.settings = (function() {
|
||||
container.empty();
|
||||
var bg = $('<span class="button-row" style="position: relative; float: right; margin-right:0;"></span>').appendTo(container);
|
||||
var input = $('<input type="text" style="width: calc(100% - 150px); margin-right: 10px;">').val(summary||"").appendTo(container);
|
||||
$('<button class="editor-button">Cancel</button>')
|
||||
$('<button class="editor-button">' + RED._("common.label.cancel") + '</button>')
|
||||
.appendTo(bg)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
updateProjectSummary(activeProject.summary, container);
|
||||
editButton.show();
|
||||
});
|
||||
$('<button class="editor-button">Save</button>')
|
||||
$('<button class="editor-button">' + RED._("common.label.save") + '</button>')
|
||||
.appendTo(bg)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@ -223,7 +223,7 @@ RED.projects.settings = (function() {
|
||||
if (summary) {
|
||||
container.text(summary).removeClass('node-info-node');
|
||||
} else {
|
||||
container.text("No summary available").addClass('node-info-none');// TODO: nls
|
||||
container.text(RED._("sidebar.project.projectSettings.noSummaryAvailable")).addClass('node-info-none');
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,7 +235,7 @@ RED.projects.settings = (function() {
|
||||
var summaryContent = $('<div></div>',{style:"color: #999"}).appendTo(summary);
|
||||
updateProjectSummary(activeProject.summary, summaryContent);
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
$('<button class="editor-button editor-button-small" style="float: right;">edit description</button>')
|
||||
$('<button class="editor-button editor-button-small" style="float: right;">' + RED._('sidebar.project.editDescription') + '</button>')
|
||||
.prependTo(summary)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@ -250,7 +250,7 @@ RED.projects.settings = (function() {
|
||||
updateProjectDescription(activeProject, descriptionContent);
|
||||
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
$('<button class="editor-button editor-button-small" style="float: right;">edit README.md</button>')
|
||||
$('<button class="editor-button editor-button-small" style="float: right;">' + RED._('sidebar.project.editReadme') + '</button>')
|
||||
.prependTo(description)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@ -316,7 +316,7 @@ RED.projects.settings = (function() {
|
||||
// depsList.editableList('addItem',{index:3, label:"Unused dependencies"}); // TODO: nls
|
||||
// }
|
||||
if (totalCount === 0) {
|
||||
depsList.editableList('addItem',{index:0, label:"None"}); // TODO: nls
|
||||
depsList.editableList('addItem',{index:0, label:RED._("sidebar.project.projectSettings.none")});
|
||||
}
|
||||
|
||||
}
|
||||
@ -381,7 +381,7 @@ RED.projects.settings = (function() {
|
||||
function createDependenciesPane(activeProject) {
|
||||
var pane = $('<div id="project-settings-tab-deps" class="project-settings-tab-pane node-help"></div>');
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
$('<button class="editor-button editor-button-small" style="margin-top:10px;float: right;">edit</button>')
|
||||
$('<button class="editor-button editor-button-small" style="margin-top:10px;float: right;">' + RED._("sidebar.project.projectSettings.edit") + '</button>')
|
||||
.appendTo(pane)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@ -451,7 +451,7 @@ RED.projects.settings = (function() {
|
||||
var buttons = $('<div class="palette-module-button-group"></div>').appendTo(metaRow);
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
if (!entry.installed && RED.settings.theme('palette.editable') !== false) {
|
||||
$('<a href="#" class="editor-button editor-button-small">install</a>').appendTo(buttons)
|
||||
$('<a href="#" class="editor-button editor-button-small">' + RED._("sidebar.project.projectSettings.install") + '</a>').appendTo(buttons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
RED.palette.editor.install(entry,row,function(err) {
|
||||
@ -468,7 +468,7 @@ RED.projects.settings = (function() {
|
||||
});
|
||||
})
|
||||
} else if (entry.known && entry.count === 0) {
|
||||
$('<a href="#" class="editor-button editor-button-small">remove from project</a>').appendTo(buttons)
|
||||
$('<a href="#" class="editor-button editor-button-small">' + RED._("sidebar.project.projectSettings.removeFromProject") + '</a>').appendTo(buttons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var deps = $.extend(true, {}, activeProject.dependencies);
|
||||
@ -484,7 +484,7 @@ RED.projects.settings = (function() {
|
||||
});
|
||||
});
|
||||
} else if (!entry.known) {
|
||||
$('<a href="#" class="editor-button editor-button-small">add to project</a>').appendTo(buttons)
|
||||
$('<a href="#" class="editor-button editor-button-small">' + RED._("sidebar.project.projectSettings.addToProject") + '</a>').appendTo(buttons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var deps = $.extend(true, {}, activeProject.dependencies);
|
||||
@ -723,10 +723,10 @@ RED.projects.settings = (function() {
|
||||
// }
|
||||
|
||||
function createFilesSection(activeProject,pane) {
|
||||
var title = $('<h3></h3>').text("Files").appendTo(pane);
|
||||
var title = $('<h3></h3>').text(RED._("sidebar.project.projectSettings.files")).appendTo(pane);
|
||||
var filesContainer = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
var editFilesButton = $('<button class="editor-button editor-button-small" style="float: right;">edit</button>')
|
||||
var editFilesButton = $('<button class="editor-button editor-button-small" style="float: right;">' + RED._('sidebar.project.projectSettings.edit') + '</button>')
|
||||
.appendTo(title)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@ -750,7 +750,7 @@ RED.projects.settings = (function() {
|
||||
|
||||
// Flow files
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(filesContainer);
|
||||
$('<label for=""></label>').text('Flow').appendTo(row);
|
||||
$('<label for=""></label>').text(RED._("sidebar.project.projectSettings.flow")).appendTo(row);
|
||||
var flowFileLabel = $('<div class="uneditable-input" style="padding:0">').appendTo(row);
|
||||
var flowFileLabelText = $('<span style="display:inline-block; padding: 6px">').text(activeProject.files.flow).appendTo(flowFileLabel);
|
||||
|
||||
@ -787,7 +787,7 @@ RED.projects.settings = (function() {
|
||||
})
|
||||
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(filesContainer);
|
||||
$('<label for=""></label>').text('Credentials').appendTo(row);
|
||||
$('<label for=""></label>').text(RED._("sidebar.project.projectSettings.credentials")).appendTo(row);
|
||||
var credFileLabel = $('<div class="uneditable-input">').text(activeProject.files.credentials).appendTo(row);
|
||||
var credFileInput = $('<div class="uneditable-input">').text(activeProject.files.credentials).hide().insertAfter(credFileLabel);
|
||||
|
||||
@ -899,12 +899,12 @@ RED.projects.settings = (function() {
|
||||
|
||||
var credentialFormRows = $('<div>',{style:"margin-top:10px"}).hide().appendTo(credentialStateLabel);
|
||||
|
||||
var credentialSetLabel = $('<div style="margin: 20px 0 10px 5px;">Set the encryption key:</div>').hide().appendTo(credentialFormRows);
|
||||
var credentialChangeLabel = $('<div style="margin: 20px 0 10px 5px;">Change the encryption key:</div>').hide().appendTo(credentialFormRows);
|
||||
var credentialResetLabel = $('<div style="margin: 20px 0 10px 5px;">Reset the encryption key:</div>').hide().appendTo(credentialFormRows);
|
||||
var credentialSetLabel = $('<div style="margin: 20px 0 10px 5px;">' + RED._("sidebar.project.projectSettings.setTheEncryptionKey") + '</div>').hide().appendTo(credentialFormRows);
|
||||
var credentialChangeLabel = $('<div style="margin: 20px 0 10px 5px;">' + RED._("sidebar.project.projectSettings.changeTheEncryptionKey") + '</div>').hide().appendTo(credentialFormRows);
|
||||
var credentialResetLabel = $('<div style="margin: 20px 0 10px 5px;">' + RED._("sidebar.project.projectSettings.resetTheEncryptionKey") + '</div>').hide().appendTo(credentialFormRows);
|
||||
|
||||
var credentialSecretExistingRow = $('<div class="user-settings-row user-settings-row-credentials"></div>').appendTo(credentialFormRows);
|
||||
$('<label for=""></label>').text('Current key').appendTo(credentialSecretExistingRow);
|
||||
$('<label for=""></label>').text(RED._("sidebar.project.projectSettings.currentKey")).appendTo(credentialSecretExistingRow);
|
||||
var credentialSecretExistingInput = $('<input type="password">').appendTo(credentialSecretExistingRow)
|
||||
.on("change keyup paste",function() {
|
||||
if (popover) {
|
||||
@ -917,10 +917,10 @@ RED.projects.settings = (function() {
|
||||
var credentialSecretNewRow = $('<div class="user-settings-row user-settings-row-credentials"></div>').appendTo(credentialFormRows);
|
||||
|
||||
|
||||
$('<label for=""></label>').text('New key').appendTo(credentialSecretNewRow);
|
||||
$('<label for=""></label>').text(RED._("sidebar.project.projectSettings.newKey")).appendTo(credentialSecretNewRow);
|
||||
var credentialSecretNewInput = $('<input type="password">').appendTo(credentialSecretNewRow).on("change keyup paste",checkFiles);
|
||||
|
||||
var credentialResetWarning = $('<div class="form-tips form-warning" style="margin: 10px;"><i class="fa fa-warning"></i> This will delete all existing credentials</div>').hide().appendTo(credentialFormRows);
|
||||
var credentialResetWarning = $('<div class="form-tips form-warning" style="margin: 10px;"><i class="fa fa-warning"></i>' + RED._("sidebar.project.projectSettings.credentialsAlert") + '</div>').hide().appendTo(credentialFormRows);
|
||||
|
||||
|
||||
var hideEditForm = function() {
|
||||
@ -950,13 +950,13 @@ RED.projects.settings = (function() {
|
||||
}
|
||||
|
||||
var formButtons = $('<span class="button-row" style="position: relative; float: right; margin-right:0;"></span>').hide().appendTo(filesContainer);
|
||||
$('<button class="editor-button">Cancel</button>')
|
||||
$('<button class="editor-button">' + RED._("common.label.cancel") + '</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
hideEditForm();
|
||||
});
|
||||
var saveButton = $('<button class="editor-button">Save</button>')
|
||||
var saveButton = $('<button class="editor-button">' + RED._("common.label.save") + '</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@ -1032,13 +1032,13 @@ RED.projects.settings = (function() {
|
||||
var updateForm = function() {
|
||||
if (activeProject.settings.credentialSecretInvalid) {
|
||||
credentialStateLabel.find(".user-settings-credentials-state-icon").removeClass().addClass("user-settings-credentials-state-icon fa fa-warning");
|
||||
credentialStateLabel.find(".user-settings-credentials-state").text("Invalid encryption key");
|
||||
credentialStateLabel.find(".user-settings-credentials-state").text(RED._("sidebar.project.projectSettings.invalidEncryptionKey"));
|
||||
} else if (activeProject.settings.credentialsEncrypted) {
|
||||
credentialStateLabel.find(".user-settings-credentials-state-icon").removeClass().addClass("user-settings-credentials-state-icon fa fa-lock");
|
||||
credentialStateLabel.find(".user-settings-credentials-state").text("Encryption enabled");
|
||||
credentialStateLabel.find(".user-settings-credentials-state").text(RED._("sidebar.project.projectSettings.encryptionEnabled"));
|
||||
} else {
|
||||
credentialStateLabel.find(".user-settings-credentials-state-icon").removeClass().addClass("user-settings-credentials-state-icon fa fa-unlock");
|
||||
credentialStateLabel.find(".user-settings-credentials-state").text("Encryption disabled");
|
||||
credentialStateLabel.find(".user-settings-credentials-state").text(RED._("sidebar.project.projectSettings.encryptionDisabled"));
|
||||
}
|
||||
credentialSecretResetButton.toggleClass('disabled',!activeProject.settings.credentialSecretInvalid && !activeProject.settings.credentialsEncrypted);
|
||||
credentialSecretResetButton.prop('disabled',!activeProject.settings.credentialSecretInvalid && !activeProject.settings.credentialsEncrypted);
|
||||
@ -1050,7 +1050,7 @@ RED.projects.settings = (function() {
|
||||
|
||||
function createLocalBranchListSection(activeProject,pane) {
|
||||
var localBranchContainer = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||
$('<h4></h4>').text("Branches").appendTo(localBranchContainer);
|
||||
$('<h4></h4>').text(RED._("sidebar.project.projectSettings.branches")).appendTo(localBranchContainer);
|
||||
|
||||
var row = $('<div class="user-settings-row projects-dialog-list"></div>').appendTo(localBranchContainer);
|
||||
|
||||
@ -1063,7 +1063,7 @@ RED.projects.settings = (function() {
|
||||
var container = $('<div class="projects-dialog-list-entry">').appendTo(row);
|
||||
if (entry.empty) {
|
||||
container.addClass('red-ui-search-empty');
|
||||
container.text("No branches");
|
||||
container.text(RED._("sidebar.project.projectSettings.noBranches"));
|
||||
return;
|
||||
}
|
||||
if (entry.current) {
|
||||
@ -1095,7 +1095,7 @@ RED.projects.settings = (function() {
|
||||
.click(function(e) {
|
||||
e.preventDefault();
|
||||
var spinner = utils.addSpinnerOverlay(row).addClass('projects-dialog-spinner-contain');
|
||||
var notification = RED.notify("Are you sure you want to delete the local branch '"+entry.name+"'? This cannot be undone.", {
|
||||
var notification = RED.notify(RED._("sidebar.project.projectSettings.deleteConfirm", { name: entry.name }), {
|
||||
type: "warning",
|
||||
modal: true,
|
||||
fixed: true,
|
||||
@ -1123,7 +1123,7 @@ RED.projects.settings = (function() {
|
||||
},
|
||||
400: {
|
||||
'git_delete_branch_unmerged': function(error) {
|
||||
notification = RED.notify("The local branch '"+entry.name+"' has unmerged changes that will be lost. Are you sure you want to delete it?", {
|
||||
notification = RED.notify(RED._("sidebar.project.projectSettings.unmergedConfirm", { name: entry.name }), {
|
||||
type: "warning",
|
||||
modal: true,
|
||||
fixed: true,
|
||||
@ -1135,7 +1135,7 @@ RED.projects.settings = (function() {
|
||||
notification.close();
|
||||
}
|
||||
},{
|
||||
text: 'Delete unmerged branch',
|
||||
text: RED._("sidebar.project.projectSettings.deleteUnmergedBranch"),
|
||||
click: function() {
|
||||
options.url += "?force=true";
|
||||
notification.close();
|
||||
@ -1183,14 +1183,14 @@ RED.projects.settings = (function() {
|
||||
}
|
||||
|
||||
function createRemoteRepositorySection(activeProject,pane) {
|
||||
$('<h3></h3>').text("Version Control").appendTo(pane);
|
||||
$('<h3></h3>').text(RED._("sidebar.project.projectSettings.versionControl")).appendTo(pane);
|
||||
|
||||
createLocalBranchListSection(activeProject,pane);
|
||||
|
||||
var repoContainer = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||
var title = $('<h4></h4>').text("Git remotes").appendTo(repoContainer);
|
||||
var title = $('<h4></h4>').text(RED._("sidebar.project.projectSettings.gitRemotes")).appendTo(repoContainer);
|
||||
|
||||
var editRepoButton = $('<button class="editor-button editor-button-small" style="float: right; margin-right: 10px;">add remote</button>')
|
||||
var editRepoButton = $('<button class="editor-button editor-button-small" style="float: right; margin-right: 10px;">' + RED._("sidebar.project.projectSettings.addRemote") + '</button>')
|
||||
.appendTo(title)
|
||||
.click(function(evt) {
|
||||
editRepoButton.attr('disabled',true);
|
||||
@ -1221,7 +1221,7 @@ RED.projects.settings = (function() {
|
||||
var container = $('<div class="projects-dialog-list-entry">').appendTo(row);
|
||||
if (entry.empty) {
|
||||
container.addClass('red-ui-search-empty');
|
||||
container.text("No remotes");
|
||||
container.text(RED._("sidebar.project.projectSettings.noRemotes"));
|
||||
return;
|
||||
} else {
|
||||
$('<span class="entry-icon"><i class="fa fa-globe"></i></span>').appendTo(container);
|
||||
@ -1240,7 +1240,7 @@ RED.projects.settings = (function() {
|
||||
.click(function(e) {
|
||||
e.preventDefault();
|
||||
var spinner = utils.addSpinnerOverlay(row).addClass('projects-dialog-spinner-contain');
|
||||
var notification = RED.notify("Are you sure you want to delete the remote '"+entry.name+"'?", {
|
||||
var notification = RED.notify(RED._("sidebar.project.projectSettings.deleteRemoteConfrim", { name: entry.name }), {
|
||||
type: "warning",
|
||||
modal: true,
|
||||
fixed: true,
|
||||
@ -1252,7 +1252,7 @@ RED.projects.settings = (function() {
|
||||
notification.close();
|
||||
}
|
||||
},{
|
||||
text: 'Delete remote',
|
||||
text: RED._("sidebar.project.projectSettings.deleteRemote"),
|
||||
click: function() {
|
||||
notification.close();
|
||||
|
||||
@ -1315,10 +1315,10 @@ RED.projects.settings = (function() {
|
||||
// var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\.git)?(?:\/?|\#[\d\w\.\-_]+?)$/.test(remoteURLInput.val());
|
||||
var validRepo = repo.length > 0 && !/\s/.test(repo);
|
||||
if (/^https?:\/\/[^/]+@/i.test(repo)) {
|
||||
remoteURLLabel.text("Do not include the username/password in the url");
|
||||
remoteURLLabel.text(RED._("sidebar.project.projectSettings.urlRule2"));
|
||||
validRepo = false;
|
||||
} else {
|
||||
remoteURLLabel.text("https://, ssh:// or file://");
|
||||
remoteURLLabel.text(RED._("sidebar.project.projectSettings.urlRule"));
|
||||
}
|
||||
saveButton.attr('disabled',(!validName || !validRepo))
|
||||
remoteNameInput.toggleClass('input-error',remoteNameInputChanged&&!validName);
|
||||
@ -1332,22 +1332,22 @@ RED.projects.settings = (function() {
|
||||
var remoteNameInputChanged = false;
|
||||
var remoteURLInputChanged = false;
|
||||
|
||||
$('<div class="projects-dialog-list-dialog-header">').text('Add remote').appendTo(addRemoteDialog);
|
||||
$('<div class="projects-dialog-list-dialog-header">').text(RED._('sidebar.project.projectSettings.addRemote2')).appendTo(addRemoteDialog);
|
||||
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(addRemoteDialog);
|
||||
$('<label for=""></label>').text('Remote name').appendTo(row);
|
||||
$('<label for=""></label>').text(RED._("sidebar.project.projectSettings.remoteName")).appendTo(row);
|
||||
var remoteNameInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
|
||||
remoteNameInputChanged = true;
|
||||
validateForm();
|
||||
});
|
||||
$('<label class="projects-edit-form-sublabel"><small>Must contain only A-Z 0-9 _ -</small></label>').appendTo(row).find("small");
|
||||
$('<label class="projects-edit-form-sublabel"><small>' + RED._("sidebar.project.projectSettings.nameRule") + '</small></label>').appendTo(row).find("small");
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(addRemoteDialog);
|
||||
$('<label for=""></label>').text('URL').appendTo(row);
|
||||
$('<label for=""></label>').text(RED._("sidebar.project.projectSettings.url")).appendTo(row);
|
||||
var remoteURLInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
|
||||
remoteURLInputChanged = true;
|
||||
validateForm()
|
||||
});
|
||||
var remoteURLLabel = $('<label class="projects-edit-form-sublabel"><small>https://, ssh:// or file://</small></label>').appendTo(row).find("small");
|
||||
var remoteURLLabel = $('<label class="projects-edit-form-sublabel"><small>' + RED._("sidebar.project.projectSettings.urlRule") +'</small></label>').appendTo(row).find("small");
|
||||
|
||||
var hideEditForm = function() {
|
||||
editRepoButton.attr('disabled',false);
|
||||
@ -1361,13 +1361,13 @@ RED.projects.settings = (function() {
|
||||
}
|
||||
var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>')
|
||||
.appendTo(addRemoteDialog);
|
||||
$('<button class="editor-button">Cancel</button>')
|
||||
$('<button class="editor-button">' + RED._("common.label.cancel") + '</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
hideEditForm();
|
||||
});
|
||||
var saveButton = $('<button class="editor-button">Add remote</button>')
|
||||
var saveButton = $('<button class="editor-button">' + RED._("sidebar.project.projectSettings.addRemote2") + '</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@ -1484,19 +1484,19 @@ RED.projects.settings = (function() {
|
||||
utils = _utils;
|
||||
addPane({
|
||||
id:'main',
|
||||
title: "Project", // TODO: nls
|
||||
title: RED._("sidebar.project.name"),
|
||||
get: createMainPane,
|
||||
close: function() { }
|
||||
});
|
||||
addPane({
|
||||
id:'deps',
|
||||
title: "Dependencies", // TODO: nls
|
||||
title: RED._("sidebar.project.dependencies"),
|
||||
get: createDependenciesPane,
|
||||
close: function() { }
|
||||
});
|
||||
addPane({
|
||||
id:'settings',
|
||||
title: "Settings", // TODO: nls
|
||||
title: RED._("sidebar.project.settings"),
|
||||
get: createSettingsPane,
|
||||
close: function() {
|
||||
if (popover) {
|
||||
|
@ -23,5 +23,6 @@ RED.state = {
|
||||
EXPORT: 6,
|
||||
IMPORT: 7,
|
||||
IMPORT_DRAGGING: 8,
|
||||
QUICK_JOINING: 9
|
||||
QUICK_JOINING: 9,
|
||||
PANNING: 10
|
||||
}
|
||||
|
@ -170,25 +170,41 @@ RED.sidebar.info = (function() {
|
||||
if (node.type === "tab") {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.status")+'</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).text((!!!node.disabled)?RED._("sidebar.info.enabled"):RED._("sidebar.info.disabled"))
|
||||
} else if (node.type === "subflow") {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("subflow.category")+'</td><td></td></tr>').appendTo(tableBody);
|
||||
var category = node.category||"subflows";
|
||||
$(propRow.children()[1]).text(RED._("palette.label."+category,{defaultValue:category}))
|
||||
}
|
||||
} else {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.node")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
|
||||
|
||||
if (node.type !== "subflow" && node.name) {
|
||||
if (node.type !== "subflow" && node.type !== "unknown" && node.name) {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("common.label.name")+'</td><td></td></tr>').appendTo(tableBody);
|
||||
$('<span class="bidiAware" dir="'+RED.text.bidi.resolveBaseTextDir(node.name)+'"></span>').text(node.name).appendTo(propRow.children()[1]);
|
||||
}
|
||||
if (!m) {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.type")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(node.type);
|
||||
$(propRow.children()[1]).text((node.type === "unknown")?node._orig.type:node.type);
|
||||
if (node.type === "unknown") {
|
||||
$('<span style="float: right; font-size: 0.8em"><i class="fa fa-warning"></i></span>').prependTo($(propRow.children()[1]))
|
||||
}
|
||||
}
|
||||
|
||||
if (!m && node.type != "subflow" && node.type != "comment") {
|
||||
if (node._def) {
|
||||
var defaults;
|
||||
if (node.type === 'unknown') {
|
||||
defaults = {};
|
||||
Object.keys(node._orig).forEach(function(k) {
|
||||
if (k !== 'type') {
|
||||
defaults[k] = {};
|
||||
}
|
||||
})
|
||||
} else if (node._def) {
|
||||
defaults = node._def.defaults;
|
||||
}
|
||||
if (defaults) {
|
||||
var count = 0;
|
||||
var defaults = node._def.defaults;
|
||||
for (var n in defaults) {
|
||||
if (n != "name" && defaults.hasOwnProperty(n)) {
|
||||
var val = node[n];
|
||||
@ -235,6 +251,9 @@ RED.sidebar.info = (function() {
|
||||
}
|
||||
}
|
||||
if (m) {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("subflow.category")+'</td><td></td></tr>').appendTo(tableBody);
|
||||
var category = subflowNode.category||"subflows";
|
||||
$(propRow.children()[1]).text(RED._("palette.label."+category,{defaultValue:category}))
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+subflowUserCount+'</td></tr>').appendTo(tableBody);
|
||||
}
|
||||
|
||||
|
164
editor/js/ui/view-navigator.js
Normal file
164
editor/js/ui/view-navigator.js
Normal file
@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
|
||||
RED.view.navigator = (function() {
|
||||
|
||||
var nav_scale = 25;
|
||||
var nav_width = 5000/nav_scale;
|
||||
var nav_height = 5000/nav_scale;
|
||||
|
||||
var navContainer;
|
||||
var navBox;
|
||||
var navBorder;
|
||||
var navVis;
|
||||
var scrollPos;
|
||||
var scaleFactor;
|
||||
var chartSize;
|
||||
var dimensions;
|
||||
var isDragging;
|
||||
var isShowing = false;
|
||||
|
||||
function refreshNodes() {
|
||||
if (!isShowing) {
|
||||
return;
|
||||
}
|
||||
var navNode = navVis.selectAll(".navnode").data(RED.view.getActiveNodes(),function(d){return d.id});
|
||||
navNode.exit().remove();
|
||||
navNode.enter().insert("rect")
|
||||
.attr('class','navnode')
|
||||
.attr("pointer-events", "none");
|
||||
navNode.each(function(d) {
|
||||
d3.select(this).attr("x",function(d) { return (d.x-d.w/2)/nav_scale })
|
||||
.attr("y",function(d) { return (d.y-d.h/2)/nav_scale })
|
||||
.attr("width",function(d) { return Math.max(9,d.w/nav_scale) })
|
||||
.attr("height",function(d) { return Math.max(3,d.h/nav_scale) })
|
||||
.attr("fill",function(d) { return d._def.color;})
|
||||
});
|
||||
}
|
||||
function onScroll() {
|
||||
if (!isDragging) {
|
||||
resizeNavBorder();
|
||||
}
|
||||
}
|
||||
function resizeNavBorder() {
|
||||
if (navBorder) {
|
||||
scaleFactor = RED.view.scale();
|
||||
chartSize = [ $("#chart").width(), $("#chart").height()];
|
||||
scrollPos = [$("#chart").scrollLeft(),$("#chart").scrollTop()];
|
||||
navBorder.attr('x',scrollPos[0]/nav_scale)
|
||||
.attr('y',scrollPos[1]/nav_scale)
|
||||
.attr('width',chartSize[0]/nav_scale/scaleFactor)
|
||||
.attr('height',chartSize[1]/nav_scale/scaleFactor)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
|
||||
$(window).resize(resizeNavBorder);
|
||||
RED.events.on("sidebar:resize",resizeNavBorder);
|
||||
|
||||
var hideTimeout;
|
||||
|
||||
navContainer = $('<div>').css({
|
||||
"position":"absolute",
|
||||
"bottom":$("#workspace-footer").height(),
|
||||
"right":0,
|
||||
zIndex: 1
|
||||
}).appendTo("#workspace").hide();
|
||||
|
||||
navBox = d3.select(navContainer[0])
|
||||
.append("svg:svg")
|
||||
.attr("width", nav_width)
|
||||
.attr("height", nav_height)
|
||||
.attr("pointer-events", "all")
|
||||
.style({
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
right:0,
|
||||
zIndex: 101,
|
||||
"border-left": "1px solid #ccc",
|
||||
"border-top": "1px solid #ccc",
|
||||
background: "rgba(245,245,245,0.5)",
|
||||
"box-shadow": "-1px 0 3px rgba(0,0,0,0.1)"
|
||||
});
|
||||
|
||||
navBox.append("rect").attr("x",0).attr("y",0).attr("width",nav_width).attr("height",nav_height).style({
|
||||
fill:"none",
|
||||
stroke:"none",
|
||||
pointerEvents:"all"
|
||||
}).on("mousedown", function() {
|
||||
// Update these in case they have changed
|
||||
scaleFactor = RED.view.scale();
|
||||
chartSize = [ $("#chart").width(), $("#chart").height()];
|
||||
dimensions = [chartSize[0]/nav_scale/scaleFactor, chartSize[1]/nav_scale/scaleFactor];
|
||||
var newX = Math.max(0,Math.min(d3.event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
|
||||
var newY = Math.max(0,Math.min(d3.event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
|
||||
navBorder.attr('x',newX).attr('y',newY);
|
||||
isDragging = true;
|
||||
$("#chart").scrollLeft(newX*nav_scale*scaleFactor);
|
||||
$("#chart").scrollTop(newY*nav_scale*scaleFactor);
|
||||
}).on("mousemove", function() {
|
||||
if (!isDragging) { return }
|
||||
if (d3.event.buttons === 0) {
|
||||
isDragging = false;
|
||||
return;
|
||||
}
|
||||
var newX = Math.max(0,Math.min(d3.event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
|
||||
var newY = Math.max(0,Math.min(d3.event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
|
||||
navBorder.attr('x',newX).attr('y',newY);
|
||||
$("#chart").scrollLeft(newX*nav_scale*scaleFactor);
|
||||
$("#chart").scrollTop(newY*nav_scale*scaleFactor);
|
||||
}).on("mouseup", function() {
|
||||
isDragging = false;
|
||||
})
|
||||
|
||||
navBorder = navBox.append("rect")
|
||||
.attr("stroke-dasharray","5,5")
|
||||
.attr("pointer-events", "none")
|
||||
.style({
|
||||
stroke: "#999",
|
||||
strokeWidth: 1,
|
||||
fill: "white",
|
||||
});
|
||||
|
||||
navVis = navBox.append("svg:g")
|
||||
|
||||
|
||||
$("#btn-navigate").click(function(evt) {
|
||||
evt.preventDefault();
|
||||
if (!isShowing) {
|
||||
isShowing = true;
|
||||
$("#btn-navigate").addClass("selected");
|
||||
resizeNavBorder();
|
||||
refreshNodes();
|
||||
$("#chart").on("scroll",onScroll);
|
||||
navContainer.fadeIn(200);
|
||||
} else {
|
||||
isShowing = false;
|
||||
navContainer.fadeOut(100);
|
||||
$("#chart").off("scroll",onScroll);
|
||||
$("#btn-navigate").removeClass("selected");
|
||||
}
|
||||
})
|
||||
},
|
||||
refresh: refreshNodes,
|
||||
resize: resizeNavBorder
|
||||
}
|
||||
|
||||
|
||||
})();
|
@ -58,7 +58,10 @@ RED.view = (function() {
|
||||
lastClickNode = null,
|
||||
dblClickPrimed = null,
|
||||
clickTime = 0,
|
||||
clickElapsed = 0;
|
||||
clickElapsed = 0,
|
||||
scroll_position = [],
|
||||
quickAddActive = false,
|
||||
quickAddLink = null;
|
||||
|
||||
var clipboard = "";
|
||||
|
||||
@ -73,6 +76,8 @@ RED.view = (function() {
|
||||
var PORT_TYPE_INPUT = 1;
|
||||
var PORT_TYPE_OUTPUT = 0;
|
||||
|
||||
var chart = $("#chart");
|
||||
|
||||
var outer = d3.select("#chart")
|
||||
.append("svg:svg")
|
||||
.attr("width", space_width)
|
||||
@ -94,6 +99,16 @@ RED.view = (function() {
|
||||
.on("mousemove", canvasMouseMove)
|
||||
.on("mousedown", canvasMouseDown)
|
||||
.on("mouseup", canvasMouseUp)
|
||||
.on("mouseenter", function() {
|
||||
if (lasso) {
|
||||
if (d3.event.buttons !== 1) {
|
||||
lasso.remove();
|
||||
lasso = null;
|
||||
}
|
||||
} else if (mouse_mode === RED.state.PANNING && d3.event.buttons !== 4) {
|
||||
resetMouseVars();
|
||||
}
|
||||
})
|
||||
.on("touchend", function() {
|
||||
clearTimeout(touchStartTime);
|
||||
touchStartTime = null;
|
||||
@ -283,7 +298,6 @@ RED.view = (function() {
|
||||
function init() {
|
||||
|
||||
RED.events.on("workspace:change",function(event) {
|
||||
var chart = $("#chart");
|
||||
if (event.old !== 0) {
|
||||
workspaceScrollPositions[event.old] = {
|
||||
left:chart.scrollLeft(),
|
||||
@ -320,6 +334,8 @@ RED.view = (function() {
|
||||
redraw();
|
||||
});
|
||||
|
||||
RED.view.navigator.init();
|
||||
|
||||
$("#btn-zoom-out").click(function() {zoomOut();});
|
||||
$("#btn-zoom-zero").click(function() {zoomZero();});
|
||||
$("#btn-zoom-in").click(function() {zoomIn();});
|
||||
@ -526,6 +542,15 @@ RED.view = (function() {
|
||||
function canvasMouseDown() {
|
||||
var point;
|
||||
|
||||
if (d3.event.button === 1) {
|
||||
// Middle Click pan
|
||||
mouse_mode = RED.state.PANNING;
|
||||
mouse_position = [d3.event.pageX,d3.event.pageY]
|
||||
scroll_position = [chart.scrollLeft(),chart.scrollTop()];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mousedown_node && !mousedown_link) {
|
||||
selected_link = null;
|
||||
updateSelection();
|
||||
@ -546,14 +571,16 @@ RED.view = (function() {
|
||||
mouse_mode = RED.state.QUICK_JOINING;
|
||||
$(window).on('keyup',disableQuickJoinEventHandler);
|
||||
}
|
||||
|
||||
quickAddActive = true;
|
||||
RED.typeSearch.show({
|
||||
x:d3.event.clientX-mainPos.left-node_width/2,
|
||||
y:d3.event.clientY-mainPos.top-node_height/2,
|
||||
cancel: function() {
|
||||
quickAddActive = false;
|
||||
resetMouseVars();
|
||||
},
|
||||
add: function(type) {
|
||||
quickAddActive = false;
|
||||
var result = addNode(type);
|
||||
if (!result) {
|
||||
return;
|
||||
@ -562,11 +589,10 @@ RED.view = (function() {
|
||||
var historyEvent = result.historyEvent;
|
||||
nn.x = point[0];
|
||||
nn.y = point[1];
|
||||
if (mouse_mode === RED.state.QUICK_JOINING) {
|
||||
if (drag_lines.length > 0) {
|
||||
var drag_line = drag_lines[0];
|
||||
if (mouse_mode === RED.state.QUICK_JOINING || quickAddLink) {
|
||||
if (quickAddLink || drag_lines.length > 0) {
|
||||
var drag_line = quickAddLink||drag_lines[0];
|
||||
var src = null,dst,src_port;
|
||||
|
||||
if (drag_line.portType === PORT_TYPE_OUTPUT && nn.inputs > 0) {
|
||||
src = drag_line.node;
|
||||
src_port = drag_line.port;
|
||||
@ -581,9 +607,9 @@ RED.view = (function() {
|
||||
RED.nodes.addLink(link);
|
||||
historyEvent.links = [link];
|
||||
hideDragLines();
|
||||
if (drag_line.portType === PORT_TYPE_OUTPUT && nn.outputs > 0) {
|
||||
if (!quickAddLink && drag_line.portType === PORT_TYPE_OUTPUT && nn.outputs > 0) {
|
||||
showDragLines([{node:nn,port:0,portType:PORT_TYPE_OUTPUT}]);
|
||||
} else if (drag_line.portType === PORT_TYPE_INPUT && nn.inputs > 0) {
|
||||
} else if (!quickAddLink && drag_line.portType === PORT_TYPE_INPUT && nn.inputs > 0) {
|
||||
showDragLines([{node:nn,port:0,portType:PORT_TYPE_INPUT}]);
|
||||
} else {
|
||||
resetMouseVars();
|
||||
@ -601,9 +627,9 @@ RED.view = (function() {
|
||||
resetMouseVars();
|
||||
}
|
||||
}
|
||||
quickAddLink = null;
|
||||
}
|
||||
|
||||
|
||||
RED.history.push(historyEvent);
|
||||
RED.nodes.add(nn);
|
||||
RED.editor.validateNode(nn);
|
||||
@ -644,7 +670,6 @@ RED.view = (function() {
|
||||
function canvasMouseMove() {
|
||||
var i;
|
||||
var node;
|
||||
mouse_position = d3.touches(this)[0]||d3.mouse(this);
|
||||
// Prevent touch scrolling...
|
||||
//if (d3.touches(this)[0]) {
|
||||
// d3.event.preventDefault();
|
||||
@ -655,6 +680,22 @@ RED.view = (function() {
|
||||
//if (point[0]-container.scrollLeft < 30 && container.scrollLeft > 0) { container.scrollLeft -= 15; }
|
||||
//console.log(d3.mouse(this),container.offsetWidth,container.offsetHeight,container.scrollLeft,container.scrollTop);
|
||||
|
||||
if (mouse_mode === RED.state.PANNING) {
|
||||
|
||||
var pos = [d3.event.pageX,d3.event.pageY];
|
||||
var deltaPos = [
|
||||
mouse_position[0]-pos[0],
|
||||
mouse_position[1]-pos[1]
|
||||
];
|
||||
|
||||
chart.scrollLeft(scroll_position[0]+deltaPos[0])
|
||||
chart.scrollTop(scroll_position[1]+deltaPos[1])
|
||||
return
|
||||
}
|
||||
|
||||
mouse_position = d3.touches(this)[0]||d3.mouse(this);
|
||||
|
||||
|
||||
if (lasso) {
|
||||
var ox = parseInt(lasso.attr("ox"));
|
||||
var oy = parseInt(lasso.attr("oy"));
|
||||
@ -906,6 +947,10 @@ RED.view = (function() {
|
||||
function canvasMouseUp() {
|
||||
var i;
|
||||
var historyEvent;
|
||||
if (mouse_mode === RED.state.PANNING) {
|
||||
resetMouseVars();
|
||||
return
|
||||
}
|
||||
if (mouse_mode === RED.state.QUICK_JOINING) {
|
||||
return;
|
||||
}
|
||||
@ -1020,17 +1065,20 @@ RED.view = (function() {
|
||||
function zoomIn() {
|
||||
if (scaleFactor < 2) {
|
||||
scaleFactor += 0.1;
|
||||
RED.view.navigator.resize();
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
function zoomOut() {
|
||||
if (scaleFactor > 0.3) {
|
||||
scaleFactor -= 0.1;
|
||||
RED.view.navigator.resize();
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
function zoomZero() {
|
||||
scaleFactor = 1;
|
||||
RED.view.navigator.resize();
|
||||
redraw();
|
||||
}
|
||||
|
||||
@ -1367,6 +1415,9 @@ RED.view = (function() {
|
||||
function disableQuickJoinEventHandler(evt) {
|
||||
// Check for ctrl (all browsers), "Meta" (Chrome/FF), keyCode 91 (Safari)
|
||||
if (evt.keyCode === 17 || evt.key === "Meta" || evt.keyCode === 91) {
|
||||
if (quickAddActive && drag_lines.length > 0) {
|
||||
quickAddLink = drag_lines[0];
|
||||
}
|
||||
resetMouseVars();
|
||||
hideDragLines();
|
||||
redraw();
|
||||
@ -1652,7 +1703,9 @@ RED.view = (function() {
|
||||
clickElapsed = now-clickTime;
|
||||
clickTime = now;
|
||||
|
||||
dblClickPrimed = (lastClickNode == mousedown_node);
|
||||
dblClickPrimed = (lastClickNode == mousedown_node &&
|
||||
d3.event.buttons === 1 &&
|
||||
!d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey);
|
||||
lastClickNode = mousedown_node;
|
||||
|
||||
var i;
|
||||
@ -2502,7 +2555,7 @@ RED.view = (function() {
|
||||
}
|
||||
).classed("link_selected", false);
|
||||
}
|
||||
|
||||
RED.view.navigator.refresh();
|
||||
if (d3.event) {
|
||||
d3.event.preventDefault();
|
||||
}
|
||||
@ -2776,7 +2829,9 @@ RED.view = (function() {
|
||||
gridSize = Math.max(5,v);
|
||||
updateGrid();
|
||||
}
|
||||
},
|
||||
getActiveNodes: function() {
|
||||
return activeNodes;
|
||||
}
|
||||
|
||||
};
|
||||
})();
|
||||
|
@ -353,3 +353,64 @@
|
||||
}
|
||||
|
||||
}
|
||||
#node-settings-icon {
|
||||
margin-left: 10px;
|
||||
width: calc(100% - 163px);
|
||||
}
|
||||
.red-ui-icon-picker {
|
||||
position: absolute;
|
||||
border: 1px solid $primary-border-color;
|
||||
box-shadow: 0 1px 6px -3px black;
|
||||
background: white;
|
||||
z-Index: 21;
|
||||
display: none;
|
||||
select {
|
||||
box-sizing: border-box;
|
||||
margin: 3px;
|
||||
width: calc(100% - 6px);
|
||||
}
|
||||
}
|
||||
.red-ui-icon-list {
|
||||
width: 308px;
|
||||
height: 200px;
|
||||
overflow-y: scroll;
|
||||
line-height: 0px;
|
||||
}
|
||||
.red-ui-icon-list-icon {
|
||||
display: inline-block;
|
||||
margin: 2px;
|
||||
padding: 4px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
&:hover {
|
||||
background: lighten($node-selected-color,20%);
|
||||
}
|
||||
&.selected {
|
||||
background: lighten($node-selected-color,20%);
|
||||
.red-ui-search-result-node {
|
||||
border-color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
.red-ui-icon-list-module {
|
||||
background: $palette-header-background;
|
||||
font-size: 0.9em;
|
||||
padding: 3px;
|
||||
color: #666;
|
||||
clear: both;
|
||||
i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.red-ui-icon-meta {
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
span {
|
||||
padding: 4px;
|
||||
color: #666;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
button {
|
||||
float: right;
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
|
@ -134,15 +134,18 @@
|
||||
color: $workspace-button-toggle-color !important;
|
||||
background:$workspace-button-background-active;
|
||||
margin-bottom: 1px;
|
||||
&.selected:not(.disabled) {
|
||||
|
||||
&.selected:not(.disabled):not(:disabled) {
|
||||
color: $workspace-button-toggle-color-selected !important;
|
||||
background: $workspace-button-background;
|
||||
border-bottom-width: 2px;
|
||||
border-bottom-color: $form-input-border-selected-color;
|
||||
margin-bottom: 0;
|
||||
&:not(.single) {
|
||||
cursor: default;
|
||||
}
|
||||
&.disabled {
|
||||
}
|
||||
&.disabled,&:disabled {
|
||||
color: $workspace-button-toggle-color-disabled !important;
|
||||
}
|
||||
}
|
||||
@ -203,7 +206,7 @@
|
||||
height: 25px;
|
||||
line-height: 23px;
|
||||
padding: 0 10px;
|
||||
|
||||
user-select: none;
|
||||
|
||||
.button-group:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
@ -227,6 +230,7 @@
|
||||
font-size: 11px;
|
||||
line-height: 17px;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
&.text-button {
|
||||
width: auto;
|
||||
padding: 0 5px;
|
||||
|
@ -214,12 +214,11 @@
|
||||
border-bottom: 1px solid $primary-border-color;
|
||||
z-index: 2;
|
||||
a {
|
||||
@include workspace-button;
|
||||
@include workspace-button-toggle;
|
||||
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) {
|
||||
|
@ -47,7 +47,9 @@
|
||||
.workspace-footer-button {
|
||||
@include component-footer-button;
|
||||
}
|
||||
|
||||
.workspace-footer-button-toggle {
|
||||
@include component-footer-button-toggle;
|
||||
}
|
||||
#workspace-footer {
|
||||
@include component-footer;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
<a class="workspace-footer-button" id="btn-zoom-out" href="#"><i class="fa fa-minus"></i></a>
|
||||
<a class="workspace-footer-button" id="btn-zoom-zero" href="#"><i class="fa fa-circle-o"></i></a>
|
||||
<a class="workspace-footer-button" id="btn-zoom-in" href="#"><i class="fa fa-plus"></i></a>
|
||||
<a class="workspace-footer-button-toggle single" id="btn-navigate" href="#"><i class="fa fa-map-o"></i></a>
|
||||
</div>
|
||||
<div id="editor-shade" class="hide"></div>
|
||||
</div>
|
||||
@ -131,6 +132,10 @@
|
||||
<i class="fa fa-tag"></i>
|
||||
<label for="subflow-input-name" data-i18n="common.label.name"></label><input type="text" id="subflow-input-name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<i class="fa fa-folder-o"></i>
|
||||
<label for="subflow-input-category" data-i18n="editor:subflow.category"></label><select style="width: 250px;" id="subflow-input-category"></select><input style="display:none; margin-left: 10px; width:calc(100% - 250px)" type="text" id="subflow-input-custom-category">
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom: 0px;">
|
||||
<label for="subflow-input-info" data-i18n="editor:subflow.info"></label>
|
||||
<a href="https://help.github.com/articles/markdown-basics/" style="font-size: 0.8em; float: right;" data-i18n="[html]subflow.format"></a>
|
||||
|
@ -6,35 +6,36 @@ module.exports = function(RED) {
|
||||
var fs = require('fs');
|
||||
|
||||
var gpioCommand = __dirname+'/nrgpio';
|
||||
var allOK = true;
|
||||
|
||||
try {
|
||||
var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString();
|
||||
if (cpuinfo.indexOf(": BCM") === -1) { throw "Info : "+RED._("rpi-gpio.errors.ignorenode"); }
|
||||
} catch(err) {
|
||||
throw "Info : "+RED._("rpi-gpio.errors.ignorenode");
|
||||
if (cpuinfo.indexOf(": BCM") === -1) {
|
||||
allOK = false;
|
||||
RED.log.warn("rpi-gpio : "+RED._("rpi-gpio.errors.ignorenode"));
|
||||
}
|
||||
|
||||
try {
|
||||
fs.statSync("/usr/share/doc/python-rpi.gpio"); // test on Raspbian
|
||||
// /usr/lib/python2.7/dist-packages/RPi/GPIO
|
||||
} catch(err) {
|
||||
try {
|
||||
fs.statSync("/usr/lib/python2.7/site-packages/RPi/GPIO"); // test on Arch
|
||||
}
|
||||
catch(err) {
|
||||
} catch(err) {
|
||||
try {
|
||||
fs.statSync("/usr/lib/python2.7/dist-packages/RPi/GPIO"); // test on Hypriot
|
||||
}
|
||||
catch(err) {
|
||||
RED.log.warn(RED._("rpi-gpio.errors.libnotfound"));
|
||||
throw "Warning : "+RED._("rpi-gpio.errors.libnotfound");
|
||||
} catch(err) {
|
||||
RED.log.warn("rpi-gpio : "+RED._("rpi-gpio.errors.libnotfound"));
|
||||
allOK = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !(1 & parseInt((fs.statSync(gpioCommand).mode & parseInt("777", 8)).toString(8)[0]) )) {
|
||||
RED.log.error(RED._("rpi-gpio.errors.needtobeexecutable",{command:gpioCommand}));
|
||||
throw "Error : "+RED._("rpi-gpio.errors.mustbeexecutable");
|
||||
RED.log.warn("rpi-gpio : "+RED._("rpi-gpio.errors.needtobeexecutable",{command:gpioCommand}));
|
||||
allOK = false;
|
||||
}
|
||||
} catch(err) {
|
||||
allOK = false;
|
||||
RED.log.warn("rpi-gpio : "+RED._("rpi-gpio.errors.ignorenode"));
|
||||
}
|
||||
|
||||
// the magic to make python print stuff immediately
|
||||
@ -61,6 +62,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
|
||||
if (allOK === true) {
|
||||
if (node.pin !== undefined) {
|
||||
node.child = spawn(gpioCommand, ["in",node.pin,node.intype,node.debounce]);
|
||||
node.running = true;
|
||||
@ -104,6 +106,19 @@ module.exports = function(RED) {
|
||||
else {
|
||||
node.warn(RED._("rpi-gpio.errors.invalidpin")+": "+node.pin);
|
||||
}
|
||||
}
|
||||
else {
|
||||
node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
|
||||
if (node.read === true) {
|
||||
var val;
|
||||
if (node.intype == "up") { val = 1; }
|
||||
if (node.intype == "down") { val = 0; }
|
||||
setTimeout(function(){
|
||||
node.send({ topic:"pi/"+node.pin, payload:val });
|
||||
node.status({fill:"grey",shape:"dot",text:RED._("rpi-gpio.status.na",{value:val})});
|
||||
},250);
|
||||
}
|
||||
}
|
||||
|
||||
node.on("close", function(done) {
|
||||
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
||||
@ -155,6 +170,7 @@ module.exports = function(RED) {
|
||||
else { node.warn(RED._("rpi-gpio.errors.invalidinput")+": "+out); }
|
||||
}
|
||||
|
||||
if (allOK === true) {
|
||||
if (node.pin !== undefined) {
|
||||
if (node.set && (node.out === "out")) {
|
||||
node.child = spawn(gpioCommand, [node.out,node.pin,node.level]);
|
||||
@ -196,6 +212,13 @@ module.exports = function(RED) {
|
||||
else {
|
||||
node.warn(RED._("rpi-gpio.errors.invalidpin")+": "+node.pin);
|
||||
}
|
||||
}
|
||||
else {
|
||||
node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
|
||||
node.on("input", function(msg){
|
||||
node.status({fill:"grey",shape:"dot",text:RED._("rpi-gpio.status.na",{value:msg.payload.toString()})});
|
||||
});
|
||||
}
|
||||
|
||||
node.on("close", function(done) {
|
||||
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
||||
@ -216,12 +239,13 @@ module.exports = function(RED) {
|
||||
this.butt = n.butt || 7;
|
||||
var node = this;
|
||||
|
||||
if (allOK === true) {
|
||||
node.child = spawn(gpioCommand+".py", ["mouse",node.butt]);
|
||||
node.status({fill:"green",shape:"dot",text:"common.status.ok"});
|
||||
|
||||
node.child.stdout.on('data', function (data) {
|
||||
data = Number(data);
|
||||
if (data === 1) { node.send({ topic:"pi/mouse", button:data, payload:1 }); }
|
||||
if (data !== 0) { node.send({ topic:"pi/mouse", button:data, payload:1 }); }
|
||||
else { node.send({ topic:"pi/mouse", button:data, payload:0 }); }
|
||||
});
|
||||
|
||||
@ -256,12 +280,17 @@ module.exports = function(RED) {
|
||||
else { done(); }
|
||||
});
|
||||
}
|
||||
else {
|
||||
node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("rpi-mouse",PiMouseNode);
|
||||
|
||||
function PiKeyboardNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var node = this;
|
||||
|
||||
if (allOK === true) {
|
||||
node.child = spawn(gpioCommand+".py", ["kbd","0"]);
|
||||
node.status({fill:"green",shape:"dot",text:"common.status.ok"});
|
||||
|
||||
@ -304,9 +333,14 @@ module.exports = function(RED) {
|
||||
else { done(); }
|
||||
});
|
||||
}
|
||||
else {
|
||||
node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("rpi-keyboard",PiKeyboardNode);
|
||||
|
||||
var pitype = { type:"" };
|
||||
if (allOK === true) {
|
||||
exec(gpioCommand+" info", function(err,stdout,stderr) {
|
||||
if (err) {
|
||||
RED.log.info(RED._("rpi-gpio.errors.version"));
|
||||
@ -321,6 +355,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.httpAdmin.get('/rpi-gpio/:id', RED.auth.needsPermission('rpi-gpio.read'), function(req,res) {
|
||||
res.json(pitype);
|
||||
|
@ -786,8 +786,8 @@
|
||||
"na": "N/A : __value__"
|
||||
},
|
||||
"errors": {
|
||||
"ignorenode": "Ignoring Raspberry Pi specific node",
|
||||
"version": "Version command failed",
|
||||
"ignorenode": "Raspberry Pi specific node set inactive",
|
||||
"version": "Failed to get version from Pi",
|
||||
"sawpitype": "Saw Pi Type",
|
||||
"libnotfound": "Cannot find Pi RPi.GPIO python library",
|
||||
"alreadyset": "GPIO pin __pin__ already set as type: __type__",
|
||||
|
@ -123,9 +123,8 @@
|
||||
},
|
||||
color:"BurlyWood",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "file.png",
|
||||
align: "right",
|
||||
outputs:1,
|
||||
icon: "file-out.png",
|
||||
label: function() {
|
||||
if (this.overwriteFile === "delete") {
|
||||
return this.name||this._("file.label.deletelabel",{file:this.filename});
|
||||
@ -159,7 +158,7 @@
|
||||
outputLabels: function(i) {
|
||||
return (this.format === "utf8") ? "UTF8 string" : "binary buffer";
|
||||
},
|
||||
icon: "file.png",
|
||||
icon: "file-in.png",
|
||||
label: function() {
|
||||
return this.name||this.filename||this._("file.label.filelabel");
|
||||
},
|
||||
|
@ -39,14 +39,20 @@ module.exports = function(RED) {
|
||||
node.tout = null;
|
||||
},333);
|
||||
}
|
||||
if (filename === "") { node.warn(RED._("file.errors.nofilename")); }
|
||||
else if (node.overwriteFile === "delete") {
|
||||
if (filename === "") {
|
||||
node.warn(RED._("file.errors.nofilename"));
|
||||
} else if (node.overwriteFile === "delete") {
|
||||
fs.unlink(filename, function (err) {
|
||||
if (err) { node.error(RED._("file.errors.deletefail",{error:err.toString()}),msg); }
|
||||
else if (RED.settings.verbose) { node.log(RED._("file.status.deletedfile",{file:filename})); }
|
||||
});
|
||||
if (err) {
|
||||
node.error(RED._("file.errors.deletefail",{error:err.toString()}),msg);
|
||||
} else {
|
||||
if (RED.settings.verbose) {
|
||||
node.log(RED._("file.status.deletedfile",{file:filename}));
|
||||
}
|
||||
else if (msg.hasOwnProperty("payload") && (typeof msg.payload !== "undefined")) {
|
||||
node.send(msg);
|
||||
}
|
||||
});
|
||||
} else if (msg.hasOwnProperty("payload") && (typeof msg.payload !== "undefined")) {
|
||||
var dir = path.dirname(filename);
|
||||
if (node.createDir) {
|
||||
try {
|
||||
@ -64,15 +70,21 @@ module.exports = function(RED) {
|
||||
if (typeof data === "boolean") { data = data.toString(); }
|
||||
if (typeof data === "number") { data = data.toString(); }
|
||||
if ((node.appendNewline) && (!Buffer.isBuffer(data))) { data += os.EOL; }
|
||||
node.data.push(Buffer.from(data));
|
||||
node.data.push({msg:msg,data:Buffer.from(data)});
|
||||
|
||||
while (node.data.length > 0) {
|
||||
if (node.overwriteFile === "true") {
|
||||
(function(packet) {
|
||||
node.wstream = fs.createWriteStream(filename, { encoding:'binary', flags:'w', autoClose:true });
|
||||
node.wstream.on("error", function(err) {
|
||||
node.error(RED._("file.errors.writefail",{error:err.toString()}),msg);
|
||||
});
|
||||
node.wstream.end(node.data.shift());
|
||||
node.wstream.on("open", function() {
|
||||
node.wstream.end(packet.data, function() {
|
||||
node.send(packet.msg);
|
||||
});
|
||||
})
|
||||
})(node.data.shift());
|
||||
}
|
||||
else {
|
||||
// Append mode
|
||||
@ -115,10 +127,17 @@ module.exports = function(RED) {
|
||||
}
|
||||
if (node.filename) {
|
||||
// Static filename - write and reuse the stream next time
|
||||
node.wstream.write(node.data.shift());
|
||||
var packet = node.data.shift()
|
||||
node.wstream.write(packet.data, function() {
|
||||
node.send(packet.msg);
|
||||
});
|
||||
|
||||
} else {
|
||||
// Dynamic filename - write and close the stream
|
||||
node.wstream.end(node.data.shift());
|
||||
var packet = node.data.shift()
|
||||
node.wstream.end(packet.data, function() {
|
||||
node.send(packet.msg);
|
||||
});
|
||||
delete node.wstream;
|
||||
delete node.wstreamIno;
|
||||
}
|
||||
|
@ -240,6 +240,7 @@
|
||||
"output": "outputs:",
|
||||
"deleteSubflow": "delete subflow",
|
||||
"info": "Description",
|
||||
"category": "Category",
|
||||
"format":"markdown format",
|
||||
"errors": {
|
||||
"noNodesSelected": "<strong>Cannot create subflow</strong>: no nodes selected",
|
||||
@ -318,6 +319,7 @@
|
||||
"noInfo": "no information available",
|
||||
"filter": "filter nodes",
|
||||
"search": "search modules",
|
||||
"addCategory": "Add new...",
|
||||
"label": {
|
||||
"subflows": "subflows",
|
||||
"input": "input",
|
||||
@ -467,8 +469,47 @@
|
||||
"description": "Description",
|
||||
"dependencies": "Dependencies",
|
||||
"settings": "Settings",
|
||||
"noSummaryAvailable": "No summary available",
|
||||
"editDescription": "Edit project description",
|
||||
"editDependencies": "Edit project dependencies",
|
||||
"editReadme": "Edit README.md",
|
||||
"projectSettings": {
|
||||
"edit": "edit",
|
||||
"none": "None",
|
||||
"install": "install",
|
||||
"removeFromProject": "remove from project",
|
||||
"addToProject": "add to project",
|
||||
"none": "None",
|
||||
"files": "Files",
|
||||
"flow": "Flow",
|
||||
"credentials": "Credentials",
|
||||
"invalidEncryptionKey": "Invalid encryption key",
|
||||
"encryptionEnabled": "Encryption enabled",
|
||||
"encryptionDisabled": "Encryption disabled",
|
||||
"resetTheEncryptionKey": "Reset the encryption key:",
|
||||
"setTheEncryptionKey": "Set the encryption key:",
|
||||
"changeTheEncryptionKey": "Change the encryption key:",
|
||||
"currentKey": "Current key",
|
||||
"newKey": "New key",
|
||||
"credentialsAlert": "This will delete all existing credentials",
|
||||
"versionControl": "Version Control",
|
||||
"branches": "Branches",
|
||||
"noBranches": "No branches",
|
||||
"deleteConfirm": "Are you sure you want to delete the local branch '__name__'? This cannot be undone.",
|
||||
"unmergedConfirm": "The local branch '__name__' has unmerged changes that will be lost. Are you sure you want to delete it?",
|
||||
"deleteUnmergedBranch": "Delete unmerged branch",
|
||||
"gitRemotes": "Git remotes",
|
||||
"addRemote": "add remote",
|
||||
"addRemote2": "Add remote",
|
||||
"remoteName": "Remote name",
|
||||
"nameRule": "Must contain only A-Z 0-9 _ -",
|
||||
"url": "URL",
|
||||
"urlRule": "https://, ssh:// or file://",
|
||||
"urlRule2": "Do not include the username/password in the URL",
|
||||
"noRemotes": "No remotes",
|
||||
"deleteRemoteConfrim": "Are you sure you want to delete the remote '__name__'?",
|
||||
"deleteRemote": "Delete remote"
|
||||
},
|
||||
"userSettings": {
|
||||
"committerDetail": "Committer Details",
|
||||
"committerTip": "Leave blank to use system default",
|
||||
|
@ -459,8 +459,46 @@
|
||||
"description": "詳細",
|
||||
"dependencies": "依存関係",
|
||||
"settings": "設定",
|
||||
"noSummaryAvailable": "サマリが存在しません",
|
||||
"editDescription": "プロジェクトの詳細を編集",
|
||||
"editDependencies": "プロジェクトの依存関係を編集",
|
||||
"editReadme": "README.mdを編集",
|
||||
"projectSettings": {
|
||||
"edit": "編集",
|
||||
"none": "なし",
|
||||
"install": "インストール",
|
||||
"removeFromProject": "プロジェクトから削除",
|
||||
"addToProject": "プロジェクトへ追加",
|
||||
"files": "ファイル",
|
||||
"flow": "フロー",
|
||||
"credentials": "認証情報",
|
||||
"invalidEncryptionKey": "不正な暗号化キー",
|
||||
"encryptionEnabled": "暗号化が有効になっています",
|
||||
"encryptionDisabled": "暗号化が無効になっています",
|
||||
"setTheEncryptionKey": "暗号化キーを設定:",
|
||||
"resetTheEncryptionKey": "暗号化キーを初期化:",
|
||||
"changeTheEncryptionKey": "暗号化キーを変更:",
|
||||
"currentKey": "現在のキー",
|
||||
"newKey": "新規のキー",
|
||||
"credentialsAlert": "既存の認証情報は全て削除されます",
|
||||
"versionControl": "バージョン管理",
|
||||
"branches": "ブランチ",
|
||||
"noBranches": "ブランチなし",
|
||||
"deleteConfirm": "本当にローカルブランチ'__name__'を削除しますか?削除すると元に戻すことはできません。",
|
||||
"unmergedConfirm": "ローカルブランチ'__name__'にはマージされていない変更があります。この変更は削除されます。本当に削除しますか?",
|
||||
"deleteUnmergedBranch": "マージされていないブランチを削除",
|
||||
"gitRemotes": "Gitリモート",
|
||||
"addRemote": "リモートを追加",
|
||||
"addRemote2": "リモートを追加",
|
||||
"remoteName": "リモート名",
|
||||
"nameRule": "A-Z 0-9 _ - のみを含む",
|
||||
"url": "URL",
|
||||
"urlRule": "https://、ssh:// または file://",
|
||||
"urlRule2": "URLにユーザ名、パスワードを含んではいけません",
|
||||
"noRemotes": "リモートなし",
|
||||
"deleteRemoteConfrim": "本当にリモート'__name__'を削除しますか?",
|
||||
"deleteRemote": "リモートを削除"
|
||||
},
|
||||
"userSettings": {
|
||||
"committerDetail": "コミッター詳細",
|
||||
"committerTip": "システムのデフォルトを使用する場合、空白のままにしてください",
|
||||
|
@ -25,6 +25,8 @@ var storageModule;
|
||||
var settingsAvailable;
|
||||
var sessionsAvailable;
|
||||
|
||||
var libraryFlowsCachedResult = null;
|
||||
|
||||
function moduleSelector(aSettings) {
|
||||
var toReturn;
|
||||
if (aSettings.storageModule) {
|
||||
@ -156,7 +158,14 @@ var storageModuleInterface = {
|
||||
if (storageModule.hasOwnProperty("getAllFlows")) {
|
||||
return storageModule.getAllFlows();
|
||||
} else {
|
||||
return listFlows("/");
|
||||
if (libraryFlowsCachedResult) {
|
||||
return Promise.resolve(libraryFlowsCachedResult);
|
||||
} else {
|
||||
return listFlows("/").then(function(result) {
|
||||
libraryFlowsCachedResult = result;
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
getFlow: function(fn) {
|
||||
@ -178,6 +187,7 @@ var storageModuleInterface = {
|
||||
err.code = "forbidden";
|
||||
return when.reject(err);
|
||||
}
|
||||
libraryFlowsCachedResult = null;
|
||||
if (storageModule.hasOwnProperty("saveFlow")) {
|
||||
return storageModule.saveFlow(fn, data);
|
||||
} else {
|
||||
|
89
test/nodes/core/hardware/36-rpi-gpio_spec.js
Normal file
89
test/nodes/core/hardware/36-rpi-gpio_spec.js
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var should = require("should");
|
||||
var rpi = require("../../../../nodes/core/hardware/36-rpi-gpio.js");
|
||||
var helper = require("node-red-node-test-helper");
|
||||
var fs = require("fs");
|
||||
|
||||
describe('RPI GPIO Node', function() {
|
||||
|
||||
before(function(done) {
|
||||
helper.startServer(done);
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
helper.stopServer(done);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
helper.unload();
|
||||
});
|
||||
|
||||
var checkIgnore = function(done) {
|
||||
setTimeout(function() {
|
||||
try {
|
||||
var logEvents = helper.log().args.filter(function(evt) {
|
||||
return ((evt[0].level == 30) && (evt[0].msg.indexOf("rpi-gpio")===0));
|
||||
});
|
||||
logEvents[0][0].should.have.a.property('msg');
|
||||
logEvents[0][0].msg.toString().should.startWith("rpi-gpio : rpi-gpio.errors.ignorenode");
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
},25);
|
||||
}
|
||||
|
||||
it('should load Input node', function(done) {
|
||||
var flow = [{id:"n1", type:"rpi-gpio in", name:"rpi-gpio in" }];
|
||||
helper.load(rpi, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
n1.should.have.property('name', 'rpi-gpio in');
|
||||
try {
|
||||
var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString();
|
||||
if (cpuinfo.indexOf(": BCM") === 1) {
|
||||
done(); // It's ON a PI ... should really do more tests !
|
||||
} else {
|
||||
checkIgnore(done);
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
checkIgnore(done);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should load Output node', function(done) {
|
||||
var flow = [{id:"n1", type:"rpi-gpio out", name:"rpi-gpio out" }];
|
||||
helper.load(rpi, flow, function() {
|
||||
var n1 = helper.getNode("n1");
|
||||
n1.should.have.property('name', 'rpi-gpio out');
|
||||
try {
|
||||
var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString();
|
||||
if (cpuinfo.indexOf(": BCM") === 1) {
|
||||
done(); // It's ON a PI ... should really do more tests !
|
||||
} else {
|
||||
checkIgnore(done);
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
checkIgnore(done);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in New Issue
Block a user