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/keyboard.js",
|
||||||
"editor/js/ui/workspaces.js",
|
"editor/js/ui/workspaces.js",
|
||||||
"editor/js/ui/view.js",
|
"editor/js/ui/view.js",
|
||||||
|
"editor/js/ui/view-navigator.js",
|
||||||
"editor/js/ui/sidebar.js",
|
"editor/js/ui/sidebar.js",
|
||||||
"editor/js/ui/palette.js",
|
"editor/js/ui/palette.js",
|
||||||
"editor/js/ui/tab-info.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) {
|
registerNodeType: function(nt,def) {
|
||||||
nodeDefinitions[nt] = def;
|
nodeDefinitions[nt] = def;
|
||||||
def.type = nt;
|
def.type = nt;
|
||||||
if (def.category != "subflows") {
|
if (nt.substring(0,8) != "subflow:") {
|
||||||
def.set = nodeSets[typeToId[nt]];
|
def.set = nodeSets[typeToId[nt]];
|
||||||
nodeSets[typeToId[nt]].added = true;
|
nodeSets[typeToId[nt]].added = true;
|
||||||
nodeSets[typeToId[nt]].enabled = true;
|
nodeSets[typeToId[nt]].enabled = true;
|
||||||
@ -356,7 +356,7 @@ RED.nodes = (function() {
|
|||||||
defaults:{name:{value:""}},
|
defaults:{name:{value:""}},
|
||||||
info: sf.info,
|
info: sf.info,
|
||||||
icon: function() { return sf.icon||"subflow.png" },
|
icon: function() { return sf.icon||"subflow.png" },
|
||||||
category: "subflows",
|
category: sf.category || "subflows",
|
||||||
inputs: sf.in.length,
|
inputs: sf.in.length,
|
||||||
outputs: sf.out.length,
|
outputs: sf.out.length,
|
||||||
color: "#da9",
|
color: "#da9",
|
||||||
@ -519,6 +519,7 @@ RED.nodes = (function() {
|
|||||||
node.type = n.type;
|
node.type = n.type;
|
||||||
node.name = n.name;
|
node.name = n.name;
|
||||||
node.info = n.info;
|
node.info = n.info;
|
||||||
|
node.category = n.category;
|
||||||
node.in = [];
|
node.in = [];
|
||||||
node.out = [];
|
node.out = [];
|
||||||
|
|
||||||
|
@ -170,8 +170,8 @@ RED.tabs = (function() {
|
|||||||
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');
|
var parentId = link.parent().attr('id');
|
||||||
wrapper.find(".red-ui-tab-link-button").removeClass("active");
|
wrapper.find(".red-ui-tab-link-button").removeClass("active selected");
|
||||||
$("#"+parentId+"-link-button").addClass("active");
|
$("#"+parentId+"-link-button").addClass("active selected");
|
||||||
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) {
|
||||||
|
@ -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;
|
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) {
|
function validateNodeEditorProperty(node,defaults,property,prefix) {
|
||||||
@ -711,6 +679,97 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
return result;
|
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) {
|
function buildLabelForm(container,node) {
|
||||||
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
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"))) {
|
if ((!node._def.defaults || !node._def.defaults.hasOwnProperty("icon"))) {
|
||||||
$('<div class="form-row"><div id="node-settings-icon"></div></div>').appendTo(dialogForm);
|
$('<hr>').appendTo(dialogForm);
|
||||||
var iconDiv = $("#node-settings-icon");
|
var iconRow = $('<div class="form-row"></div>').appendTo(dialogForm);
|
||||||
$('<label data-i18n="editor.settingIcon">').appendTo(iconDiv);
|
$('<label style="width: 50px" data-i18n="editor.settingIcon">').appendTo(iconRow);
|
||||||
var iconForm = $('<div>',{class:"node-label-form-row"});
|
|
||||||
iconForm.appendTo(iconDiv);
|
|
||||||
$('<label>').appendTo(iconForm);
|
|
||||||
|
|
||||||
var selectIconModule = $('<select id="node-settings-icon-module"><option value=""></option></select>').appendTo(iconForm);
|
var iconButton = $('<button class="editor-button">').appendTo(iconRow);
|
||||||
var iconPath;
|
|
||||||
if (node.icon) {
|
|
||||||
iconPath = RED.utils.separateIconPath(node.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));
|
|
||||||
});
|
|
||||||
if (iconPath.module && !iconSets[iconPath.module]) {
|
|
||||||
selectIconModule.append($("<option disabled></option>").val(iconPath.module).text(iconPath.module));
|
|
||||||
}
|
|
||||||
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);
|
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconButton);
|
||||||
selectIconModule.change(function() {
|
var colour = node._def.color;
|
||||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, true);
|
var icon_url = RED.utils.getNodeIcon(node._def,node);
|
||||||
});
|
nodeDiv.css('backgroundColor',colour);
|
||||||
var iconFileHidden = $('<input type="hidden" id="node-settings-icon-file-hidden"></input>').appendTo(iconForm);
|
var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
||||||
iconFileHidden.val(iconPath.file);
|
var iconDiv = $('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer);
|
||||||
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);
|
iconButton.click(function(e) {
|
||||||
var iconFileList = iconSets[selectIconModule.val()];
|
e.preventDefault();
|
||||||
if (!iconFileList || iconFileList.indexOf(iconPath.file) === -1) {
|
var iconPath;
|
||||||
selectIconFile.append($("<option disabled></option>").val(iconPath.file).text(iconPath.file));
|
var icon = $("#node-settings-icon").text()||"";
|
||||||
}
|
if (icon) {
|
||||||
selectIconFile.val(iconPath.file);
|
iconPath = RED.utils.separateIconPath(icon);
|
||||||
}
|
} else {
|
||||||
}
|
iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||||
|
|
||||||
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));
|
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+")");
|
||||||
|
});
|
||||||
|
})
|
||||||
|
$('<div class="uneditable-input" id="node-settings-icon">').text(node.icon).appendTo(iconRow);
|
||||||
}
|
}
|
||||||
selectIconFile.prop("disabled", !iconFileList);
|
|
||||||
selectIconFile.removeClass("input-error");
|
|
||||||
selectIconModule.removeClass("input-error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLabels(editing_node, changes, outputMap) {
|
function updateLabels(editing_node, changes, outputMap) {
|
||||||
@ -1086,9 +1100,7 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!editing_node._def.defaults || !editing_node._def.defaults.hasOwnProperty("icon")) {
|
if (!editing_node._def.defaults || !editing_node._def.defaults.hasOwnProperty("icon")) {
|
||||||
var iconModule = $("#node-settings-icon-module-hidden").val();
|
var icon = $("#node-settings-icon").text()||""
|
||||||
var iconFile = $("#node-settings-icon-file-hidden").val();
|
|
||||||
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
|
|
||||||
if (!isDefaultIcon) {
|
if (!isDefaultIcon) {
|
||||||
if (icon !== editing_node.icon) {
|
if (icon !== editing_node.icon) {
|
||||||
changes.icon = editing_node.icon;
|
changes.icon = editing_node.icon;
|
||||||
@ -1692,15 +1704,28 @@ RED.editor = (function() {
|
|||||||
if (updateLabels(editing_node, changes, null)) {
|
if (updateLabels(editing_node, changes, null)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
var iconModule = $("#node-settings-icon-module-hidden").val();
|
var icon = $("#node-settings-icon").text()||"";
|
||||||
var iconFile = $("#node-settings-icon-file-hidden").val();
|
|
||||||
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
|
|
||||||
if ((editing_node.icon === undefined && icon !== "node-red/subflow.png") ||
|
if ((editing_node.icon === undefined && icon !== "node-red/subflow.png") ||
|
||||||
(editing_node.icon !== undefined && editing_node.icon !== icon)) {
|
(editing_node.icon !== undefined && editing_node.icon !== icon)) {
|
||||||
changes.icon = editing_node.icon;
|
changes.icon = editing_node.icon;
|
||||||
editing_node.icon = icon;
|
editing_node.icon = icon;
|
||||||
changed = true;
|
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();
|
RED.palette.refresh();
|
||||||
|
|
||||||
@ -1773,8 +1798,6 @@ RED.editor = (function() {
|
|||||||
});
|
});
|
||||||
portLabels.content.addClass("editor-tray-content");
|
portLabels.content.addClass("editor-tray-content");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (editing_node) {
|
if (editing_node) {
|
||||||
RED.sidebar.info.refresh(editing_node);
|
RED.sidebar.info.refresh(editing_node);
|
||||||
}
|
}
|
||||||
@ -1787,6 +1810,33 @@ RED.editor = (function() {
|
|||||||
|
|
||||||
$("#subflow-input-name").val(subflow.name);
|
$("#subflow-input-name").val(subflow.name);
|
||||||
RED.text.bidi.prepareInput($("#subflow-input-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);
|
subflowEditor.getSession().setValue(subflow.info||"",-1);
|
||||||
var userCount = 0;
|
var userCount = 0;
|
||||||
var subflowType = "subflow:"+editing_node.id;
|
var subflowType = "subflow:"+editing_node.id;
|
||||||
@ -1799,7 +1849,6 @@ RED.editor = (function() {
|
|||||||
$("#subflow-dialog-user-count").text(RED._("subflow.subflowInstances", {count:userCount})).show();
|
$("#subflow-dialog-user-count").text(RED._("subflow.subflowInstances", {count:userCount})).show();
|
||||||
|
|
||||||
buildLabelForm(portLabels.content,subflow);
|
buildLabelForm(portLabels.content,subflow);
|
||||||
validateIcon(subflow);
|
|
||||||
trayBody.i18n();
|
trayBody.i18n();
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
|
@ -21,7 +21,18 @@ RED.palette = (function() {
|
|||||||
|
|
||||||
var categoryContainers = {};
|
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, " ");
|
label = (label || category).replace(/_/g, " ");
|
||||||
var catDiv = $('<div id="palette-container-'+category+'" class="palette-category palette-close hide">'+
|
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>'+
|
'<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 id="palette-'+category+'-function"></div>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'</div>').appendTo("#palette-container");
|
'</div>').appendTo("#palette-container");
|
||||||
|
catDiv.data('category',originalCategory);
|
||||||
|
catDiv.data('label',label);
|
||||||
categoryContainers[category] = {
|
categoryContainers[category] = {
|
||||||
container: catDiv,
|
container: catDiv,
|
||||||
close: function() {
|
close: function() {
|
||||||
@ -133,6 +145,7 @@ RED.palette = (function() {
|
|||||||
}
|
}
|
||||||
if (exclusion.indexOf(def.category)===-1) {
|
if (exclusion.indexOf(def.category)===-1) {
|
||||||
|
|
||||||
|
var originalCategory = def.category;
|
||||||
var category = def.category.replace(/ /g,"_");
|
var category = def.category.replace(/ /g,"_");
|
||||||
var rootCategory = category.split("-")[0];
|
var rootCategory = category.split("-")[0];
|
||||||
|
|
||||||
@ -153,7 +166,6 @@ RED.palette = (function() {
|
|||||||
|
|
||||||
d.className="palette_node";
|
d.className="palette_node";
|
||||||
|
|
||||||
|
|
||||||
if (def.icon) {
|
if (def.icon) {
|
||||||
var icon_url = RED.utils.getNodeIcon(def);
|
var icon_url = RED.utils.getNodeIcon(def);
|
||||||
var iconContainer = $('<div/>',{class:"palette_icon_container"+(def.align=="right"?" palette_icon_container_right":"")}).appendTo(d);
|
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);
|
d.appendChild(portIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($("#palette-base-category-"+rootCategory).length === 0) {
|
createCategory(def.category,rootCategory,category,(coreCategories.indexOf(rootCategory) !== -1)?"node-red":def.set.id);
|
||||||
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>');
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#palette-"+category).append(d);
|
$("#palette-"+category).append(d);
|
||||||
|
|
||||||
|
$(d).data('category',rootCategory);
|
||||||
|
|
||||||
d.onmousedown = function(e) { e.preventDefault(); };
|
d.onmousedown = function(e) { e.preventDefault(); };
|
||||||
|
|
||||||
var popover = RED.popover.create({
|
var popover = RED.popover.create({
|
||||||
@ -308,7 +311,7 @@ RED.palette = (function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var nodeInfo = null;
|
var nodeInfo = null;
|
||||||
if (def.category == "subflows") {
|
if (nt.indexOf("subflow:") === 0) {
|
||||||
$(d).dblclick(function(e) {
|
$(d).dblclick(function(e) {
|
||||||
RED.workspaces.show(nt.substring(8));
|
RED.workspaces.show(nt.substring(8));
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -382,6 +385,31 @@ RED.palette = (function() {
|
|||||||
}
|
}
|
||||||
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,marked(sf.info||""));
|
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,marked(sf.info||""));
|
||||||
setIcon(paletteNode,sf);
|
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 = coreCategories
|
||||||
}
|
}
|
||||||
categoryList.forEach(function(category){
|
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) {
|
$("#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 {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
add:addNodeType,
|
add:addNodeType,
|
||||||
remove:removeNodeType,
|
remove:removeNodeType,
|
||||||
hide:hideNodeType,
|
hide:hideNodeType,
|
||||||
show:showNodeType,
|
show:showNodeType,
|
||||||
refresh:refreshNodeTypes
|
refresh:refreshNodeTypes,
|
||||||
|
getCategories: getCategories
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
@ -49,7 +49,7 @@ RED.projects.settings = (function() {
|
|||||||
var tabContainer;
|
var tabContainer;
|
||||||
|
|
||||||
var trayOptions = {
|
var trayOptions = {
|
||||||
title: "Project Settings",// RED._("menu.label.userSettings"),, // TODO: nls
|
title: RED._("menu.label.userSettings"),
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
id: "node-dialog-ok",
|
id: "node-dialog-ok",
|
||||||
@ -173,14 +173,14 @@ RED.projects.settings = (function() {
|
|||||||
container.empty();
|
container.empty();
|
||||||
var bg = $('<span class="button-row" style="position: relative; float: right; margin-right:0;"></span>').appendTo(container);
|
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);
|
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)
|
.appendTo(bg)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
updateProjectSummary(activeProject.summary, container);
|
updateProjectSummary(activeProject.summary, container);
|
||||||
editButton.show();
|
editButton.show();
|
||||||
});
|
});
|
||||||
$('<button class="editor-button">Save</button>')
|
$('<button class="editor-button">' + RED._("common.label.save") + '</button>')
|
||||||
.appendTo(bg)
|
.appendTo(bg)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
@ -223,7 +223,7 @@ RED.projects.settings = (function() {
|
|||||||
if (summary) {
|
if (summary) {
|
||||||
container.text(summary).removeClass('node-info-node');
|
container.text(summary).removeClass('node-info-node');
|
||||||
} else {
|
} 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);
|
var summaryContent = $('<div></div>',{style:"color: #999"}).appendTo(summary);
|
||||||
updateProjectSummary(activeProject.summary, summaryContent);
|
updateProjectSummary(activeProject.summary, summaryContent);
|
||||||
if (RED.user.hasPermission("projects.write")) {
|
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)
|
.prependTo(summary)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
@ -250,7 +250,7 @@ RED.projects.settings = (function() {
|
|||||||
updateProjectDescription(activeProject, descriptionContent);
|
updateProjectDescription(activeProject, descriptionContent);
|
||||||
|
|
||||||
if (RED.user.hasPermission("projects.write")) {
|
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)
|
.prependTo(description)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
@ -316,7 +316,7 @@ RED.projects.settings = (function() {
|
|||||||
// depsList.editableList('addItem',{index:3, label:"Unused dependencies"}); // TODO: nls
|
// depsList.editableList('addItem',{index:3, label:"Unused dependencies"}); // TODO: nls
|
||||||
// }
|
// }
|
||||||
if (totalCount === 0) {
|
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) {
|
function createDependenciesPane(activeProject) {
|
||||||
var pane = $('<div id="project-settings-tab-deps" class="project-settings-tab-pane node-help"></div>');
|
var pane = $('<div id="project-settings-tab-deps" class="project-settings-tab-pane node-help"></div>');
|
||||||
if (RED.user.hasPermission("projects.write")) {
|
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)
|
.appendTo(pane)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
@ -451,7 +451,7 @@ RED.projects.settings = (function() {
|
|||||||
var buttons = $('<div class="palette-module-button-group"></div>').appendTo(metaRow);
|
var buttons = $('<div class="palette-module-button-group"></div>').appendTo(metaRow);
|
||||||
if (RED.user.hasPermission("projects.write")) {
|
if (RED.user.hasPermission("projects.write")) {
|
||||||
if (!entry.installed && RED.settings.theme('palette.editable') !== false) {
|
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) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
RED.palette.editor.install(entry,row,function(err) {
|
RED.palette.editor.install(entry,row,function(err) {
|
||||||
@ -468,7 +468,7 @@ RED.projects.settings = (function() {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
} else if (entry.known && entry.count === 0) {
|
} 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) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
var deps = $.extend(true, {}, activeProject.dependencies);
|
var deps = $.extend(true, {}, activeProject.dependencies);
|
||||||
@ -484,7 +484,7 @@ RED.projects.settings = (function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (!entry.known) {
|
} 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) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
var deps = $.extend(true, {}, activeProject.dependencies);
|
var deps = $.extend(true, {}, activeProject.dependencies);
|
||||||
@ -723,10 +723,10 @@ RED.projects.settings = (function() {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
function createFilesSection(activeProject,pane) {
|
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);
|
var filesContainer = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||||
if (RED.user.hasPermission("projects.write")) {
|
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)
|
.appendTo(title)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
@ -750,7 +750,7 @@ RED.projects.settings = (function() {
|
|||||||
|
|
||||||
// Flow files
|
// Flow files
|
||||||
row = $('<div class="user-settings-row"></div>').appendTo(filesContainer);
|
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 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);
|
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);
|
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 credFileLabel = $('<div class="uneditable-input">').text(activeProject.files.credentials).appendTo(row);
|
||||||
var credFileInput = $('<div class="uneditable-input">').text(activeProject.files.credentials).hide().insertAfter(credFileLabel);
|
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 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 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;">Change the encryption key:</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;">Reset the encryption key:</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);
|
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)
|
var credentialSecretExistingInput = $('<input type="password">').appendTo(credentialSecretExistingRow)
|
||||||
.on("change keyup paste",function() {
|
.on("change keyup paste",function() {
|
||||||
if (popover) {
|
if (popover) {
|
||||||
@ -917,10 +917,10 @@ RED.projects.settings = (function() {
|
|||||||
var credentialSecretNewRow = $('<div class="user-settings-row user-settings-row-credentials"></div>').appendTo(credentialFormRows);
|
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 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() {
|
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);
|
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)
|
.appendTo(formButtons)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
hideEditForm();
|
hideEditForm();
|
||||||
});
|
});
|
||||||
var saveButton = $('<button class="editor-button">Save</button>')
|
var saveButton = $('<button class="editor-button">' + RED._("common.label.save") + '</button>')
|
||||||
.appendTo(formButtons)
|
.appendTo(formButtons)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
@ -1032,13 +1032,13 @@ RED.projects.settings = (function() {
|
|||||||
var updateForm = function() {
|
var updateForm = function() {
|
||||||
if (activeProject.settings.credentialSecretInvalid) {
|
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-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) {
|
} 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-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 {
|
} else {
|
||||||
credentialStateLabel.find(".user-settings-credentials-state-icon").removeClass().addClass("user-settings-credentials-state-icon fa fa-unlock");
|
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.toggleClass('disabled',!activeProject.settings.credentialSecretInvalid && !activeProject.settings.credentialsEncrypted);
|
||||||
credentialSecretResetButton.prop('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) {
|
function createLocalBranchListSection(activeProject,pane) {
|
||||||
var localBranchContainer = $('<div class="user-settings-section"></div>').appendTo(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);
|
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);
|
var container = $('<div class="projects-dialog-list-entry">').appendTo(row);
|
||||||
if (entry.empty) {
|
if (entry.empty) {
|
||||||
container.addClass('red-ui-search-empty');
|
container.addClass('red-ui-search-empty');
|
||||||
container.text("No branches");
|
container.text(RED._("sidebar.project.projectSettings.noBranches"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (entry.current) {
|
if (entry.current) {
|
||||||
@ -1095,7 +1095,7 @@ RED.projects.settings = (function() {
|
|||||||
.click(function(e) {
|
.click(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var spinner = utils.addSpinnerOverlay(row).addClass('projects-dialog-spinner-contain');
|
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",
|
type: "warning",
|
||||||
modal: true,
|
modal: true,
|
||||||
fixed: true,
|
fixed: true,
|
||||||
@ -1123,7 +1123,7 @@ RED.projects.settings = (function() {
|
|||||||
},
|
},
|
||||||
400: {
|
400: {
|
||||||
'git_delete_branch_unmerged': function(error) {
|
'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",
|
type: "warning",
|
||||||
modal: true,
|
modal: true,
|
||||||
fixed: true,
|
fixed: true,
|
||||||
@ -1135,7 +1135,7 @@ RED.projects.settings = (function() {
|
|||||||
notification.close();
|
notification.close();
|
||||||
}
|
}
|
||||||
},{
|
},{
|
||||||
text: 'Delete unmerged branch',
|
text: RED._("sidebar.project.projectSettings.deleteUnmergedBranch"),
|
||||||
click: function() {
|
click: function() {
|
||||||
options.url += "?force=true";
|
options.url += "?force=true";
|
||||||
notification.close();
|
notification.close();
|
||||||
@ -1183,14 +1183,14 @@ RED.projects.settings = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createRemoteRepositorySection(activeProject,pane) {
|
function createRemoteRepositorySection(activeProject,pane) {
|
||||||
$('<h3></h3>').text("Version Control").appendTo(pane);
|
$('<h3></h3>').text(RED._("sidebar.project.projectSettings.versionControl")).appendTo(pane);
|
||||||
|
|
||||||
createLocalBranchListSection(activeProject,pane);
|
createLocalBranchListSection(activeProject,pane);
|
||||||
|
|
||||||
var repoContainer = $('<div class="user-settings-section"></div>').appendTo(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)
|
.appendTo(title)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
editRepoButton.attr('disabled',true);
|
editRepoButton.attr('disabled',true);
|
||||||
@ -1221,7 +1221,7 @@ RED.projects.settings = (function() {
|
|||||||
var container = $('<div class="projects-dialog-list-entry">').appendTo(row);
|
var container = $('<div class="projects-dialog-list-entry">').appendTo(row);
|
||||||
if (entry.empty) {
|
if (entry.empty) {
|
||||||
container.addClass('red-ui-search-empty');
|
container.addClass('red-ui-search-empty');
|
||||||
container.text("No remotes");
|
container.text(RED._("sidebar.project.projectSettings.noRemotes"));
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
$('<span class="entry-icon"><i class="fa fa-globe"></i></span>').appendTo(container);
|
$('<span class="entry-icon"><i class="fa fa-globe"></i></span>').appendTo(container);
|
||||||
@ -1240,7 +1240,7 @@ RED.projects.settings = (function() {
|
|||||||
.click(function(e) {
|
.click(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var spinner = utils.addSpinnerOverlay(row).addClass('projects-dialog-spinner-contain');
|
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",
|
type: "warning",
|
||||||
modal: true,
|
modal: true,
|
||||||
fixed: true,
|
fixed: true,
|
||||||
@ -1252,7 +1252,7 @@ RED.projects.settings = (function() {
|
|||||||
notification.close();
|
notification.close();
|
||||||
}
|
}
|
||||||
},{
|
},{
|
||||||
text: 'Delete remote',
|
text: RED._("sidebar.project.projectSettings.deleteRemote"),
|
||||||
click: function() {
|
click: function() {
|
||||||
notification.close();
|
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 = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\.git)?(?:\/?|\#[\d\w\.\-_]+?)$/.test(remoteURLInput.val());
|
||||||
var validRepo = repo.length > 0 && !/\s/.test(repo);
|
var validRepo = repo.length > 0 && !/\s/.test(repo);
|
||||||
if (/^https?:\/\/[^/]+@/i.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;
|
validRepo = false;
|
||||||
} else {
|
} else {
|
||||||
remoteURLLabel.text("https://, ssh:// or file://");
|
remoteURLLabel.text(RED._("sidebar.project.projectSettings.urlRule"));
|
||||||
}
|
}
|
||||||
saveButton.attr('disabled',(!validName || !validRepo))
|
saveButton.attr('disabled',(!validName || !validRepo))
|
||||||
remoteNameInput.toggleClass('input-error',remoteNameInputChanged&&!validName);
|
remoteNameInput.toggleClass('input-error',remoteNameInputChanged&&!validName);
|
||||||
@ -1332,22 +1332,22 @@ RED.projects.settings = (function() {
|
|||||||
var remoteNameInputChanged = false;
|
var remoteNameInputChanged = false;
|
||||||
var remoteURLInputChanged = 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);
|
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() {
|
var remoteNameInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
|
||||||
remoteNameInputChanged = true;
|
remoteNameInputChanged = true;
|
||||||
validateForm();
|
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);
|
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() {
|
var remoteURLInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
|
||||||
remoteURLInputChanged = true;
|
remoteURLInputChanged = true;
|
||||||
validateForm()
|
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() {
|
var hideEditForm = function() {
|
||||||
editRepoButton.attr('disabled',false);
|
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>')
|
var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>')
|
||||||
.appendTo(addRemoteDialog);
|
.appendTo(addRemoteDialog);
|
||||||
$('<button class="editor-button">Cancel</button>')
|
$('<button class="editor-button">' + RED._("common.label.cancel") + '</button>')
|
||||||
.appendTo(formButtons)
|
.appendTo(formButtons)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
hideEditForm();
|
hideEditForm();
|
||||||
});
|
});
|
||||||
var saveButton = $('<button class="editor-button">Add remote</button>')
|
var saveButton = $('<button class="editor-button">' + RED._("sidebar.project.projectSettings.addRemote2") + '</button>')
|
||||||
.appendTo(formButtons)
|
.appendTo(formButtons)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
@ -1484,19 +1484,19 @@ RED.projects.settings = (function() {
|
|||||||
utils = _utils;
|
utils = _utils;
|
||||||
addPane({
|
addPane({
|
||||||
id:'main',
|
id:'main',
|
||||||
title: "Project", // TODO: nls
|
title: RED._("sidebar.project.name"),
|
||||||
get: createMainPane,
|
get: createMainPane,
|
||||||
close: function() { }
|
close: function() { }
|
||||||
});
|
});
|
||||||
addPane({
|
addPane({
|
||||||
id:'deps',
|
id:'deps',
|
||||||
title: "Dependencies", // TODO: nls
|
title: RED._("sidebar.project.dependencies"),
|
||||||
get: createDependenciesPane,
|
get: createDependenciesPane,
|
||||||
close: function() { }
|
close: function() { }
|
||||||
});
|
});
|
||||||
addPane({
|
addPane({
|
||||||
id:'settings',
|
id:'settings',
|
||||||
title: "Settings", // TODO: nls
|
title: RED._("sidebar.project.settings"),
|
||||||
get: createSettingsPane,
|
get: createSettingsPane,
|
||||||
close: function() {
|
close: function() {
|
||||||
if (popover) {
|
if (popover) {
|
||||||
|
@ -23,5 +23,6 @@ RED.state = {
|
|||||||
EXPORT: 6,
|
EXPORT: 6,
|
||||||
IMPORT: 7,
|
IMPORT: 7,
|
||||||
IMPORT_DRAGGING: 8,
|
IMPORT_DRAGGING: 8,
|
||||||
QUICK_JOINING: 9
|
QUICK_JOINING: 9,
|
||||||
|
PANNING: 10
|
||||||
}
|
}
|
||||||
|
@ -170,25 +170,41 @@ RED.sidebar.info = (function() {
|
|||||||
if (node.type === "tab") {
|
if (node.type === "tab") {
|
||||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.status")+'</td><td></td></tr>').appendTo(tableBody);
|
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"))
|
$(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 {
|
} else {
|
||||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.node")+"</td><td></td></tr>").appendTo(tableBody);
|
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]);
|
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);
|
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]);
|
$('<span class="bidiAware" dir="'+RED.text.bidi.resolveBaseTextDir(node.name)+'"></span>').text(node.name).appendTo(propRow.children()[1]);
|
||||||
}
|
}
|
||||||
if (!m) {
|
if (!m) {
|
||||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.type")+"</td><td></td></tr>").appendTo(tableBody);
|
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 (!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 count = 0;
|
||||||
var defaults = node._def.defaults;
|
|
||||||
for (var n in defaults) {
|
for (var n in defaults) {
|
||||||
if (n != "name" && defaults.hasOwnProperty(n)) {
|
if (n != "name" && defaults.hasOwnProperty(n)) {
|
||||||
var val = node[n];
|
var val = node[n];
|
||||||
@ -235,6 +251,9 @@ RED.sidebar.info = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m) {
|
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);
|
$('<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,
|
lastClickNode = null,
|
||||||
dblClickPrimed = null,
|
dblClickPrimed = null,
|
||||||
clickTime = 0,
|
clickTime = 0,
|
||||||
clickElapsed = 0;
|
clickElapsed = 0,
|
||||||
|
scroll_position = [],
|
||||||
|
quickAddActive = false,
|
||||||
|
quickAddLink = null;
|
||||||
|
|
||||||
var clipboard = "";
|
var clipboard = "";
|
||||||
|
|
||||||
@ -73,6 +76,8 @@ RED.view = (function() {
|
|||||||
var PORT_TYPE_INPUT = 1;
|
var PORT_TYPE_INPUT = 1;
|
||||||
var PORT_TYPE_OUTPUT = 0;
|
var PORT_TYPE_OUTPUT = 0;
|
||||||
|
|
||||||
|
var chart = $("#chart");
|
||||||
|
|
||||||
var outer = d3.select("#chart")
|
var outer = d3.select("#chart")
|
||||||
.append("svg:svg")
|
.append("svg:svg")
|
||||||
.attr("width", space_width)
|
.attr("width", space_width)
|
||||||
@ -94,6 +99,16 @@ RED.view = (function() {
|
|||||||
.on("mousemove", canvasMouseMove)
|
.on("mousemove", canvasMouseMove)
|
||||||
.on("mousedown", canvasMouseDown)
|
.on("mousedown", canvasMouseDown)
|
||||||
.on("mouseup", canvasMouseUp)
|
.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() {
|
.on("touchend", function() {
|
||||||
clearTimeout(touchStartTime);
|
clearTimeout(touchStartTime);
|
||||||
touchStartTime = null;
|
touchStartTime = null;
|
||||||
@ -283,7 +298,6 @@ RED.view = (function() {
|
|||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
RED.events.on("workspace:change",function(event) {
|
RED.events.on("workspace:change",function(event) {
|
||||||
var chart = $("#chart");
|
|
||||||
if (event.old !== 0) {
|
if (event.old !== 0) {
|
||||||
workspaceScrollPositions[event.old] = {
|
workspaceScrollPositions[event.old] = {
|
||||||
left:chart.scrollLeft(),
|
left:chart.scrollLeft(),
|
||||||
@ -320,6 +334,8 @@ RED.view = (function() {
|
|||||||
redraw();
|
redraw();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RED.view.navigator.init();
|
||||||
|
|
||||||
$("#btn-zoom-out").click(function() {zoomOut();});
|
$("#btn-zoom-out").click(function() {zoomOut();});
|
||||||
$("#btn-zoom-zero").click(function() {zoomZero();});
|
$("#btn-zoom-zero").click(function() {zoomZero();});
|
||||||
$("#btn-zoom-in").click(function() {zoomIn();});
|
$("#btn-zoom-in").click(function() {zoomIn();});
|
||||||
@ -526,6 +542,15 @@ RED.view = (function() {
|
|||||||
function canvasMouseDown() {
|
function canvasMouseDown() {
|
||||||
var point;
|
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) {
|
if (!mousedown_node && !mousedown_link) {
|
||||||
selected_link = null;
|
selected_link = null;
|
||||||
updateSelection();
|
updateSelection();
|
||||||
@ -546,14 +571,16 @@ RED.view = (function() {
|
|||||||
mouse_mode = RED.state.QUICK_JOINING;
|
mouse_mode = RED.state.QUICK_JOINING;
|
||||||
$(window).on('keyup',disableQuickJoinEventHandler);
|
$(window).on('keyup',disableQuickJoinEventHandler);
|
||||||
}
|
}
|
||||||
|
quickAddActive = true;
|
||||||
RED.typeSearch.show({
|
RED.typeSearch.show({
|
||||||
x:d3.event.clientX-mainPos.left-node_width/2,
|
x:d3.event.clientX-mainPos.left-node_width/2,
|
||||||
y:d3.event.clientY-mainPos.top-node_height/2,
|
y:d3.event.clientY-mainPos.top-node_height/2,
|
||||||
cancel: function() {
|
cancel: function() {
|
||||||
|
quickAddActive = false;
|
||||||
resetMouseVars();
|
resetMouseVars();
|
||||||
},
|
},
|
||||||
add: function(type) {
|
add: function(type) {
|
||||||
|
quickAddActive = false;
|
||||||
var result = addNode(type);
|
var result = addNode(type);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return;
|
||||||
@ -562,11 +589,10 @@ RED.view = (function() {
|
|||||||
var historyEvent = result.historyEvent;
|
var historyEvent = result.historyEvent;
|
||||||
nn.x = point[0];
|
nn.x = point[0];
|
||||||
nn.y = point[1];
|
nn.y = point[1];
|
||||||
if (mouse_mode === RED.state.QUICK_JOINING) {
|
if (mouse_mode === RED.state.QUICK_JOINING || quickAddLink) {
|
||||||
if (drag_lines.length > 0) {
|
if (quickAddLink || drag_lines.length > 0) {
|
||||||
var drag_line = drag_lines[0];
|
var drag_line = quickAddLink||drag_lines[0];
|
||||||
var src = null,dst,src_port;
|
var src = null,dst,src_port;
|
||||||
|
|
||||||
if (drag_line.portType === PORT_TYPE_OUTPUT && nn.inputs > 0) {
|
if (drag_line.portType === PORT_TYPE_OUTPUT && nn.inputs > 0) {
|
||||||
src = drag_line.node;
|
src = drag_line.node;
|
||||||
src_port = drag_line.port;
|
src_port = drag_line.port;
|
||||||
@ -581,9 +607,9 @@ RED.view = (function() {
|
|||||||
RED.nodes.addLink(link);
|
RED.nodes.addLink(link);
|
||||||
historyEvent.links = [link];
|
historyEvent.links = [link];
|
||||||
hideDragLines();
|
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}]);
|
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}]);
|
showDragLines([{node:nn,port:0,portType:PORT_TYPE_INPUT}]);
|
||||||
} else {
|
} else {
|
||||||
resetMouseVars();
|
resetMouseVars();
|
||||||
@ -601,9 +627,9 @@ RED.view = (function() {
|
|||||||
resetMouseVars();
|
resetMouseVars();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
quickAddLink = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RED.history.push(historyEvent);
|
RED.history.push(historyEvent);
|
||||||
RED.nodes.add(nn);
|
RED.nodes.add(nn);
|
||||||
RED.editor.validateNode(nn);
|
RED.editor.validateNode(nn);
|
||||||
@ -644,7 +670,6 @@ RED.view = (function() {
|
|||||||
function canvasMouseMove() {
|
function canvasMouseMove() {
|
||||||
var i;
|
var i;
|
||||||
var node;
|
var node;
|
||||||
mouse_position = d3.touches(this)[0]||d3.mouse(this);
|
|
||||||
// Prevent touch scrolling...
|
// Prevent touch scrolling...
|
||||||
//if (d3.touches(this)[0]) {
|
//if (d3.touches(this)[0]) {
|
||||||
// d3.event.preventDefault();
|
// d3.event.preventDefault();
|
||||||
@ -655,6 +680,22 @@ RED.view = (function() {
|
|||||||
//if (point[0]-container.scrollLeft < 30 && container.scrollLeft > 0) { container.scrollLeft -= 15; }
|
//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);
|
//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) {
|
if (lasso) {
|
||||||
var ox = parseInt(lasso.attr("ox"));
|
var ox = parseInt(lasso.attr("ox"));
|
||||||
var oy = parseInt(lasso.attr("oy"));
|
var oy = parseInt(lasso.attr("oy"));
|
||||||
@ -906,6 +947,10 @@ RED.view = (function() {
|
|||||||
function canvasMouseUp() {
|
function canvasMouseUp() {
|
||||||
var i;
|
var i;
|
||||||
var historyEvent;
|
var historyEvent;
|
||||||
|
if (mouse_mode === RED.state.PANNING) {
|
||||||
|
resetMouseVars();
|
||||||
|
return
|
||||||
|
}
|
||||||
if (mouse_mode === RED.state.QUICK_JOINING) {
|
if (mouse_mode === RED.state.QUICK_JOINING) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1020,17 +1065,20 @@ RED.view = (function() {
|
|||||||
function zoomIn() {
|
function zoomIn() {
|
||||||
if (scaleFactor < 2) {
|
if (scaleFactor < 2) {
|
||||||
scaleFactor += 0.1;
|
scaleFactor += 0.1;
|
||||||
|
RED.view.navigator.resize();
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function zoomOut() {
|
function zoomOut() {
|
||||||
if (scaleFactor > 0.3) {
|
if (scaleFactor > 0.3) {
|
||||||
scaleFactor -= 0.1;
|
scaleFactor -= 0.1;
|
||||||
|
RED.view.navigator.resize();
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function zoomZero() {
|
function zoomZero() {
|
||||||
scaleFactor = 1;
|
scaleFactor = 1;
|
||||||
|
RED.view.navigator.resize();
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,6 +1415,9 @@ RED.view = (function() {
|
|||||||
function disableQuickJoinEventHandler(evt) {
|
function disableQuickJoinEventHandler(evt) {
|
||||||
// Check for ctrl (all browsers), "Meta" (Chrome/FF), keyCode 91 (Safari)
|
// Check for ctrl (all browsers), "Meta" (Chrome/FF), keyCode 91 (Safari)
|
||||||
if (evt.keyCode === 17 || evt.key === "Meta" || evt.keyCode === 91) {
|
if (evt.keyCode === 17 || evt.key === "Meta" || evt.keyCode === 91) {
|
||||||
|
if (quickAddActive && drag_lines.length > 0) {
|
||||||
|
quickAddLink = drag_lines[0];
|
||||||
|
}
|
||||||
resetMouseVars();
|
resetMouseVars();
|
||||||
hideDragLines();
|
hideDragLines();
|
||||||
redraw();
|
redraw();
|
||||||
@ -1652,7 +1703,9 @@ RED.view = (function() {
|
|||||||
clickElapsed = now-clickTime;
|
clickElapsed = now-clickTime;
|
||||||
clickTime = now;
|
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;
|
lastClickNode = mousedown_node;
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
@ -2502,7 +2555,7 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
).classed("link_selected", false);
|
).classed("link_selected", false);
|
||||||
}
|
}
|
||||||
|
RED.view.navigator.refresh();
|
||||||
if (d3.event) {
|
if (d3.event) {
|
||||||
d3.event.preventDefault();
|
d3.event.preventDefault();
|
||||||
}
|
}
|
||||||
@ -2776,7 +2829,9 @@ RED.view = (function() {
|
|||||||
gridSize = Math.max(5,v);
|
gridSize = Math.max(5,v);
|
||||||
updateGrid();
|
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;
|
color: $workspace-button-toggle-color !important;
|
||||||
background:$workspace-button-background-active;
|
background:$workspace-button-background-active;
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
&.selected:not(.disabled) {
|
|
||||||
|
&.selected:not(.disabled):not(:disabled) {
|
||||||
color: $workspace-button-toggle-color-selected !important;
|
color: $workspace-button-toggle-color-selected !important;
|
||||||
background: $workspace-button-background;
|
background: $workspace-button-background;
|
||||||
border-bottom-width: 2px;
|
border-bottom-width: 2px;
|
||||||
border-bottom-color: $form-input-border-selected-color;
|
border-bottom-color: $form-input-border-selected-color;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
cursor: default;
|
&:not(.single) {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&.disabled {
|
&.disabled,&:disabled {
|
||||||
color: $workspace-button-toggle-color-disabled !important;
|
color: $workspace-button-toggle-color-disabled !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,7 +206,7 @@
|
|||||||
height: 25px;
|
height: 25px;
|
||||||
line-height: 23px;
|
line-height: 23px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
.button-group:not(:last-child) {
|
.button-group:not(:last-child) {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
@ -227,6 +230,7 @@
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
line-height: 17px;
|
line-height: 17px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
&.text-button {
|
&.text-button {
|
||||||
width: auto;
|
width: auto;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
|
@ -214,12 +214,11 @@
|
|||||||
border-bottom: 1px solid $primary-border-color;
|
border-bottom: 1px solid $primary-border-color;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
a {
|
a {
|
||||||
@include workspace-button;
|
@include workspace-button-toggle;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
width: 28px;
|
width: 28px;
|
||||||
margin: 4px 3px 3px;
|
margin: 4px 3px 3px;
|
||||||
border: 1px solid $primary-border-color;
|
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
&.red-ui-tab-link-button {
|
&.red-ui-tab-link-button {
|
||||||
&:not(.active) {
|
&:not(.active) {
|
||||||
|
@ -47,7 +47,9 @@
|
|||||||
.workspace-footer-button {
|
.workspace-footer-button {
|
||||||
@include component-footer-button;
|
@include component-footer-button;
|
||||||
}
|
}
|
||||||
|
.workspace-footer-button-toggle {
|
||||||
|
@include component-footer-button-toggle;
|
||||||
|
}
|
||||||
#workspace-footer {
|
#workspace-footer {
|
||||||
@include component-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-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-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" 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>
|
||||||
<div id="editor-shade" class="hide"></div>
|
<div id="editor-shade" class="hide"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -131,6 +132,10 @@
|
|||||||
<i class="fa fa-tag"></i>
|
<i class="fa fa-tag"></i>
|
||||||
<label for="subflow-input-name" data-i18n="common.label.name"></label><input type="text" id="subflow-input-name">
|
<label for="subflow-input-name" data-i18n="common.label.name"></label><input type="text" id="subflow-input-name">
|
||||||
</div>
|
</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;">
|
<div class="form-row" style="margin-bottom: 0px;">
|
||||||
<label for="subflow-input-info" data-i18n="editor:subflow.info"></label>
|
<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>
|
<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 fs = require('fs');
|
||||||
|
|
||||||
var gpioCommand = __dirname+'/nrgpio';
|
var gpioCommand = __dirname+'/nrgpio';
|
||||||
|
var allOK = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString();
|
var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString();
|
||||||
if (cpuinfo.indexOf(": BCM") === -1) { throw "Info : "+RED._("rpi-gpio.errors.ignorenode"); }
|
if (cpuinfo.indexOf(": BCM") === -1) {
|
||||||
} catch(err) {
|
allOK = false;
|
||||||
throw "Info : "+RED._("rpi-gpio.errors.ignorenode");
|
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 {
|
try {
|
||||||
fs.statSync("/usr/lib/python2.7/site-packages/RPi/GPIO"); // test on Arch
|
fs.statSync("/usr/share/doc/python-rpi.gpio"); // test on Raspbian
|
||||||
}
|
// /usr/lib/python2.7/dist-packages/RPi/GPIO
|
||||||
catch(err) {
|
} catch(err) {
|
||||||
try {
|
try {
|
||||||
fs.statSync("/usr/lib/python2.7/dist-packages/RPi/GPIO"); // test on Hypriot
|
fs.statSync("/usr/lib/python2.7/site-packages/RPi/GPIO"); // test on Arch
|
||||||
}
|
} catch(err) {
|
||||||
catch(err) {
|
try {
|
||||||
RED.log.warn(RED._("rpi-gpio.errors.libnotfound"));
|
fs.statSync("/usr/lib/python2.7/dist-packages/RPi/GPIO"); // test on Hypriot
|
||||||
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.warn("rpi-gpio : "+RED._("rpi-gpio.errors.needtobeexecutable",{command:gpioCommand}));
|
||||||
if ( !(1 & parseInt((fs.statSync(gpioCommand).mode & parseInt("777", 8)).toString(8)[0]) )) {
|
allOK = false;
|
||||||
RED.log.error(RED._("rpi-gpio.errors.needtobeexecutable",{command:gpioCommand}));
|
}
|
||||||
throw "Error : "+RED._("rpi-gpio.errors.mustbeexecutable");
|
} catch(err) {
|
||||||
|
allOK = false;
|
||||||
|
RED.log.warn("rpi-gpio : "+RED._("rpi-gpio.errors.ignorenode"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// the magic to make python print stuff immediately
|
// the magic to make python print stuff immediately
|
||||||
@ -61,48 +62,62 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.pin !== undefined) {
|
if (allOK === true) {
|
||||||
node.child = spawn(gpioCommand, ["in",node.pin,node.intype,node.debounce]);
|
if (node.pin !== undefined) {
|
||||||
node.running = true;
|
node.child = spawn(gpioCommand, ["in",node.pin,node.intype,node.debounce]);
|
||||||
node.status({fill:"green",shape:"dot",text:"common.status.ok"});
|
node.running = true;
|
||||||
|
node.status({fill:"green",shape:"dot",text:"common.status.ok"});
|
||||||
|
|
||||||
node.child.stdout.on('data', function (data) {
|
node.child.stdout.on('data', function (data) {
|
||||||
var d = data.toString().trim().split("\n");
|
var d = data.toString().trim().split("\n");
|
||||||
for (var i = 0; i < d.length; i++) {
|
for (var i = 0; i < d.length; i++) {
|
||||||
if (d[i] === '') { return; }
|
if (d[i] === '') { return; }
|
||||||
if (node.running && node.buttonState !== -1 && !isNaN(Number(d[i])) && node.buttonState !== d[i]) {
|
if (node.running && node.buttonState !== -1 && !isNaN(Number(d[i])) && node.buttonState !== d[i]) {
|
||||||
node.send({ topic:"pi/"+node.pin, payload:Number(d[i]) });
|
node.send({ topic:"pi/"+node.pin, payload:Number(d[i]) });
|
||||||
|
}
|
||||||
|
node.buttonState = d[i];
|
||||||
|
node.status({fill:"green",shape:"dot",text:d[i]});
|
||||||
|
if (RED.settings.verbose) { node.log("out: "+d[i]+" :"); }
|
||||||
}
|
}
|
||||||
node.buttonState = d[i];
|
});
|
||||||
node.status({fill:"green",shape:"dot",text:d[i]});
|
|
||||||
if (RED.settings.verbose) { node.log("out: "+d[i]+" :"); }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
node.child.stderr.on('data', function (data) {
|
node.child.stderr.on('data', function (data) {
|
||||||
if (RED.settings.verbose) { node.log("err: "+data+" :"); }
|
if (RED.settings.verbose) { node.log("err: "+data+" :"); }
|
||||||
});
|
});
|
||||||
|
|
||||||
node.child.on('close', function (code) {
|
node.child.on('close', function (code) {
|
||||||
node.running = false;
|
node.running = false;
|
||||||
node.child = null;
|
node.child = null;
|
||||||
if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); }
|
if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); }
|
||||||
if (node.done) {
|
if (node.done) {
|
||||||
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
||||||
node.done();
|
node.done();
|
||||||
}
|
}
|
||||||
else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); }
|
else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); }
|
||||||
});
|
});
|
||||||
|
|
||||||
node.child.on('error', function (err) {
|
node.child.on('error', function (err) {
|
||||||
if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); }
|
if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); }
|
||||||
else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); }
|
else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); }
|
||||||
else { node.error(RED._("rpi-gpio.errors.error",{error:err.errno})) }
|
else { node.error(RED._("rpi-gpio.errors.error",{error:err.errno})) }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.warn(RED._("rpi-gpio.errors.invalidpin")+": "+node.pin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node.warn(RED._("rpi-gpio.errors.invalidpin")+": "+node.pin);
|
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.on("close", function(done) {
|
||||||
@ -155,20 +170,83 @@ module.exports = function(RED) {
|
|||||||
else { node.warn(RED._("rpi-gpio.errors.invalidinput")+": "+out); }
|
else { node.warn(RED._("rpi-gpio.errors.invalidinput")+": "+out); }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.pin !== undefined) {
|
if (allOK === true) {
|
||||||
if (node.set && (node.out === "out")) {
|
if (node.pin !== undefined) {
|
||||||
node.child = spawn(gpioCommand, [node.out,node.pin,node.level]);
|
if (node.set && (node.out === "out")) {
|
||||||
node.status({fill:"green",shape:"dot",text:node.level});
|
node.child = spawn(gpioCommand, [node.out,node.pin,node.level]);
|
||||||
} else {
|
node.status({fill:"green",shape:"dot",text:node.level});
|
||||||
node.child = spawn(gpioCommand, [node.out,node.pin,node.freq]);
|
} else {
|
||||||
node.status({fill:"green",shape:"dot",text:"common.status.ok"});
|
node.child = spawn(gpioCommand, [node.out,node.pin,node.freq]);
|
||||||
}
|
node.status({fill:"green",shape:"dot",text:"common.status.ok"});
|
||||||
node.running = true;
|
}
|
||||||
|
node.running = true;
|
||||||
|
|
||||||
node.on("input", inputlistener);
|
node.on("input", inputlistener);
|
||||||
|
|
||||||
|
node.child.stdout.on('data', function (data) {
|
||||||
|
if (RED.settings.verbose) { node.log("out: "+data+" :"); }
|
||||||
|
});
|
||||||
|
|
||||||
|
node.child.stderr.on('data', function (data) {
|
||||||
|
if (RED.settings.verbose) { node.log("err: "+data+" :"); }
|
||||||
|
});
|
||||||
|
|
||||||
|
node.child.on('close', function (code) {
|
||||||
|
node.child = null;
|
||||||
|
node.running = false;
|
||||||
|
if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); }
|
||||||
|
if (node.done) {
|
||||||
|
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
||||||
|
node.done();
|
||||||
|
}
|
||||||
|
else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); }
|
||||||
|
});
|
||||||
|
|
||||||
|
node.child.on('error', function (err) {
|
||||||
|
if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); }
|
||||||
|
else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); }
|
||||||
|
else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); }
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
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"});
|
||||||
|
delete pinsInUse[node.pin];
|
||||||
|
if (node.child != null) {
|
||||||
|
node.done = done;
|
||||||
|
node.child.stdin.write("close "+node.pin);
|
||||||
|
node.child.kill('SIGKILL');
|
||||||
|
}
|
||||||
|
else { done(); }
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
RED.nodes.registerType("rpi-gpio out",GPIOOutNode);
|
||||||
|
|
||||||
|
function PiMouseNode(n) {
|
||||||
|
RED.nodes.createNode(this,n);
|
||||||
|
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) {
|
node.child.stdout.on('data', function (data) {
|
||||||
if (RED.settings.verbose) { node.log("out: "+data+" :"); }
|
data = Number(data);
|
||||||
|
if (data !== 0) { node.send({ topic:"pi/mouse", button:data, payload:1 }); }
|
||||||
|
else { node.send({ topic:"pi/mouse", button:data, payload:0 }); }
|
||||||
});
|
});
|
||||||
|
|
||||||
node.child.stderr.on('data', function (data) {
|
node.child.stderr.on('data', function (data) {
|
||||||
@ -192,69 +270,19 @@ module.exports = function(RED) {
|
|||||||
else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); }
|
else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
node.on("close", function(done) {
|
||||||
|
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
||||||
|
if (node.child != null) {
|
||||||
|
node.done = done;
|
||||||
|
node.child.kill('SIGINT');
|
||||||
|
node.child = null;
|
||||||
|
}
|
||||||
|
else { done(); }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node.warn(RED._("rpi-gpio.errors.invalidpin")+": "+node.pin);
|
node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
|
||||||
}
|
}
|
||||||
|
|
||||||
node.on("close", function(done) {
|
|
||||||
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
|
||||||
delete pinsInUse[node.pin];
|
|
||||||
if (node.child != null) {
|
|
||||||
node.done = done;
|
|
||||||
node.child.stdin.write("close "+node.pin);
|
|
||||||
node.child.kill('SIGKILL');
|
|
||||||
}
|
|
||||||
else { done(); }
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
RED.nodes.registerType("rpi-gpio out",GPIOOutNode);
|
|
||||||
|
|
||||||
function PiMouseNode(n) {
|
|
||||||
RED.nodes.createNode(this,n);
|
|
||||||
this.butt = n.butt || 7;
|
|
||||||
var node = this;
|
|
||||||
|
|
||||||
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 }); }
|
|
||||||
else { node.send({ topic:"pi/mouse", button:data, payload:0 }); }
|
|
||||||
});
|
|
||||||
|
|
||||||
node.child.stderr.on('data', function (data) {
|
|
||||||
if (RED.settings.verbose) { node.log("err: "+data+" :"); }
|
|
||||||
});
|
|
||||||
|
|
||||||
node.child.on('close', function (code) {
|
|
||||||
node.child = null;
|
|
||||||
node.running = false;
|
|
||||||
if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); }
|
|
||||||
if (node.done) {
|
|
||||||
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
|
||||||
node.done();
|
|
||||||
}
|
|
||||||
else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); }
|
|
||||||
});
|
|
||||||
|
|
||||||
node.child.on('error', function (err) {
|
|
||||||
if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); }
|
|
||||||
else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); }
|
|
||||||
else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); }
|
|
||||||
});
|
|
||||||
|
|
||||||
node.on("close", function(done) {
|
|
||||||
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
|
||||||
if (node.child != null) {
|
|
||||||
node.done = done;
|
|
||||||
node.child.kill('SIGINT');
|
|
||||||
node.child = null;
|
|
||||||
}
|
|
||||||
else { done(); }
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
RED.nodes.registerType("rpi-mouse",PiMouseNode);
|
RED.nodes.registerType("rpi-mouse",PiMouseNode);
|
||||||
|
|
||||||
@ -262,39 +290,40 @@ module.exports = function(RED) {
|
|||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
var node = this;
|
var node = this;
|
||||||
|
|
||||||
node.child = spawn(gpioCommand+".py", ["kbd","0"]);
|
if (allOK === true) {
|
||||||
node.status({fill:"green",shape:"dot",text:"common.status.ok"});
|
node.child = spawn(gpioCommand+".py", ["kbd","0"]);
|
||||||
|
node.status({fill:"green",shape:"dot",text:"common.status.ok"});
|
||||||
|
|
||||||
node.child.stdout.on('data', function (data) {
|
node.child.stdout.on('data', function (data) {
|
||||||
var b = data.toString().trim().split(",");
|
var b = data.toString().trim().split(",");
|
||||||
var act = "up";
|
var act = "up";
|
||||||
if (b[1] === "1") { act = "down"; }
|
if (b[1] === "1") { act = "down"; }
|
||||||
if (b[1] === "2") { act = "repeat"; }
|
if (b[1] === "2") { act = "repeat"; }
|
||||||
node.send({ topic:"pi/key", payload:Number(b[0]), action:act });
|
node.send({ topic:"pi/key", payload:Number(b[0]), action:act });
|
||||||
});
|
});
|
||||||
|
|
||||||
node.child.stderr.on('data', function (data) {
|
node.child.stderr.on('data', function (data) {
|
||||||
if (RED.settings.verbose) { node.log("err: "+data+" :"); }
|
if (RED.settings.verbose) { node.log("err: "+data+" :"); }
|
||||||
});
|
});
|
||||||
|
|
||||||
node.child.on('close', function (code) {
|
node.child.on('close', function (code) {
|
||||||
node.running = false;
|
node.running = false;
|
||||||
node.child = null;
|
node.child = null;
|
||||||
if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); }
|
if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); }
|
||||||
if (node.done) {
|
if (node.done) {
|
||||||
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"});
|
||||||
node.done();
|
node.done();
|
||||||
}
|
}
|
||||||
else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); }
|
else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); }
|
||||||
});
|
});
|
||||||
|
|
||||||
node.child.on('error', function (err) {
|
node.child.on('error', function (err) {
|
||||||
if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); }
|
if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); }
|
||||||
else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); }
|
else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); }
|
||||||
else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); }
|
else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); }
|
||||||
});
|
});
|
||||||
|
|
||||||
node.on("close", function(done) {
|
node.on("close", function(done) {
|
||||||
node.status({});
|
node.status({});
|
||||||
if (node.child != null) {
|
if (node.child != null) {
|
||||||
node.done = done;
|
node.done = done;
|
||||||
@ -303,24 +332,30 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
else { done(); }
|
else { done(); }
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
RED.nodes.registerType("rpi-keyboard",PiKeyboardNode);
|
RED.nodes.registerType("rpi-keyboard",PiKeyboardNode);
|
||||||
|
|
||||||
var pitype = { type:"" };
|
var pitype = { type:"" };
|
||||||
exec(gpioCommand+" info", function(err,stdout,stderr) {
|
if (allOK === true) {
|
||||||
if (err) {
|
exec(gpioCommand+" info", function(err,stdout,stderr) {
|
||||||
RED.log.info(RED._("rpi-gpio.errors.version"));
|
if (err) {
|
||||||
}
|
RED.log.info(RED._("rpi-gpio.errors.version"));
|
||||||
else {
|
|
||||||
try {
|
|
||||||
var info = JSON.parse( stdout.trim().replace(/\'/g,"\"") );
|
|
||||||
pitype.type = info["TYPE"];
|
|
||||||
}
|
}
|
||||||
catch(e) {
|
else {
|
||||||
RED.log.info(RED._("rpi-gpio.errors.sawpitype"),stdout.trim());
|
try {
|
||||||
|
var info = JSON.parse( stdout.trim().replace(/\'/g,"\"") );
|
||||||
|
pitype.type = info["TYPE"];
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
RED.log.info(RED._("rpi-gpio.errors.sawpitype"),stdout.trim());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
RED.httpAdmin.get('/rpi-gpio/:id', RED.auth.needsPermission('rpi-gpio.read'), function(req,res) {
|
RED.httpAdmin.get('/rpi-gpio/:id', RED.auth.needsPermission('rpi-gpio.read'), function(req,res) {
|
||||||
res.json(pitype);
|
res.json(pitype);
|
||||||
|
@ -786,8 +786,8 @@
|
|||||||
"na": "N/A : __value__"
|
"na": "N/A : __value__"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"ignorenode": "Ignoring Raspberry Pi specific node",
|
"ignorenode": "Raspberry Pi specific node set inactive",
|
||||||
"version": "Version command failed",
|
"version": "Failed to get version from Pi",
|
||||||
"sawpitype": "Saw Pi Type",
|
"sawpitype": "Saw Pi Type",
|
||||||
"libnotfound": "Cannot find Pi RPi.GPIO python library",
|
"libnotfound": "Cannot find Pi RPi.GPIO python library",
|
||||||
"alreadyset": "GPIO pin __pin__ already set as type: __type__",
|
"alreadyset": "GPIO pin __pin__ already set as type: __type__",
|
||||||
|
@ -123,9 +123,8 @@
|
|||||||
},
|
},
|
||||||
color:"BurlyWood",
|
color:"BurlyWood",
|
||||||
inputs:1,
|
inputs:1,
|
||||||
outputs:0,
|
outputs:1,
|
||||||
icon: "file.png",
|
icon: "file-out.png",
|
||||||
align: "right",
|
|
||||||
label: function() {
|
label: function() {
|
||||||
if (this.overwriteFile === "delete") {
|
if (this.overwriteFile === "delete") {
|
||||||
return this.name||this._("file.label.deletelabel",{file:this.filename});
|
return this.name||this._("file.label.deletelabel",{file:this.filename});
|
||||||
@ -159,7 +158,7 @@
|
|||||||
outputLabels: function(i) {
|
outputLabels: function(i) {
|
||||||
return (this.format === "utf8") ? "UTF8 string" : "binary buffer";
|
return (this.format === "utf8") ? "UTF8 string" : "binary buffer";
|
||||||
},
|
},
|
||||||
icon: "file.png",
|
icon: "file-in.png",
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.name||this.filename||this._("file.label.filelabel");
|
return this.name||this.filename||this._("file.label.filelabel");
|
||||||
},
|
},
|
||||||
|
@ -39,14 +39,20 @@ module.exports = function(RED) {
|
|||||||
node.tout = null;
|
node.tout = null;
|
||||||
},333);
|
},333);
|
||||||
}
|
}
|
||||||
if (filename === "") { node.warn(RED._("file.errors.nofilename")); }
|
if (filename === "") {
|
||||||
else if (node.overwriteFile === "delete") {
|
node.warn(RED._("file.errors.nofilename"));
|
||||||
|
} else if (node.overwriteFile === "delete") {
|
||||||
fs.unlink(filename, function (err) {
|
fs.unlink(filename, function (err) {
|
||||||
if (err) { node.error(RED._("file.errors.deletefail",{error:err.toString()}),msg); }
|
if (err) {
|
||||||
else if (RED.settings.verbose) { node.log(RED._("file.status.deletedfile",{file:filename})); }
|
node.error(RED._("file.errors.deletefail",{error:err.toString()}),msg);
|
||||||
|
} else {
|
||||||
|
if (RED.settings.verbose) {
|
||||||
|
node.log(RED._("file.status.deletedfile",{file:filename}));
|
||||||
|
}
|
||||||
|
node.send(msg);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
} else if (msg.hasOwnProperty("payload") && (typeof msg.payload !== "undefined")) {
|
||||||
else if (msg.hasOwnProperty("payload") && (typeof msg.payload !== "undefined")) {
|
|
||||||
var dir = path.dirname(filename);
|
var dir = path.dirname(filename);
|
||||||
if (node.createDir) {
|
if (node.createDir) {
|
||||||
try {
|
try {
|
||||||
@ -64,15 +70,21 @@ module.exports = function(RED) {
|
|||||||
if (typeof data === "boolean") { data = data.toString(); }
|
if (typeof data === "boolean") { data = data.toString(); }
|
||||||
if (typeof data === "number") { data = data.toString(); }
|
if (typeof data === "number") { data = data.toString(); }
|
||||||
if ((node.appendNewline) && (!Buffer.isBuffer(data))) { data += os.EOL; }
|
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) {
|
while (node.data.length > 0) {
|
||||||
if (node.overwriteFile === "true") {
|
if (node.overwriteFile === "true") {
|
||||||
node.wstream = fs.createWriteStream(filename, { encoding:'binary', flags:'w', autoClose:true });
|
(function(packet) {
|
||||||
node.wstream.on("error", function(err) {
|
node.wstream = fs.createWriteStream(filename, { encoding:'binary', flags:'w', autoClose:true });
|
||||||
node.error(RED._("file.errors.writefail",{error:err.toString()}),msg);
|
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 {
|
else {
|
||||||
// Append mode
|
// Append mode
|
||||||
@ -115,10 +127,17 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
if (node.filename) {
|
if (node.filename) {
|
||||||
// Static filename - write and reuse the stream next time
|
// 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 {
|
} else {
|
||||||
// Dynamic filename - write and close the stream
|
// 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.wstream;
|
||||||
delete node.wstreamIno;
|
delete node.wstreamIno;
|
||||||
}
|
}
|
||||||
|
@ -240,6 +240,7 @@
|
|||||||
"output": "outputs:",
|
"output": "outputs:",
|
||||||
"deleteSubflow": "delete subflow",
|
"deleteSubflow": "delete subflow",
|
||||||
"info": "Description",
|
"info": "Description",
|
||||||
|
"category": "Category",
|
||||||
"format":"markdown format",
|
"format":"markdown format",
|
||||||
"errors": {
|
"errors": {
|
||||||
"noNodesSelected": "<strong>Cannot create subflow</strong>: no nodes selected",
|
"noNodesSelected": "<strong>Cannot create subflow</strong>: no nodes selected",
|
||||||
@ -318,6 +319,7 @@
|
|||||||
"noInfo": "no information available",
|
"noInfo": "no information available",
|
||||||
"filter": "filter nodes",
|
"filter": "filter nodes",
|
||||||
"search": "search modules",
|
"search": "search modules",
|
||||||
|
"addCategory": "Add new...",
|
||||||
"label": {
|
"label": {
|
||||||
"subflows": "subflows",
|
"subflows": "subflows",
|
||||||
"input": "input",
|
"input": "input",
|
||||||
@ -467,8 +469,47 @@
|
|||||||
"description": "Description",
|
"description": "Description",
|
||||||
"dependencies": "Dependencies",
|
"dependencies": "Dependencies",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
|
"noSummaryAvailable": "No summary available",
|
||||||
"editDescription": "Edit project description",
|
"editDescription": "Edit project description",
|
||||||
"editDependencies": "Edit project dependencies",
|
"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": {
|
"userSettings": {
|
||||||
"committerDetail": "Committer Details",
|
"committerDetail": "Committer Details",
|
||||||
"committerTip": "Leave blank to use system default",
|
"committerTip": "Leave blank to use system default",
|
||||||
|
@ -459,8 +459,46 @@
|
|||||||
"description": "詳細",
|
"description": "詳細",
|
||||||
"dependencies": "依存関係",
|
"dependencies": "依存関係",
|
||||||
"settings": "設定",
|
"settings": "設定",
|
||||||
|
"noSummaryAvailable": "サマリが存在しません",
|
||||||
"editDescription": "プロジェクトの詳細を編集",
|
"editDescription": "プロジェクトの詳細を編集",
|
||||||
"editDependencies": "プロジェクトの依存関係を編集",
|
"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": {
|
"userSettings": {
|
||||||
"committerDetail": "コミッター詳細",
|
"committerDetail": "コミッター詳細",
|
||||||
"committerTip": "システムのデフォルトを使用する場合、空白のままにしてください",
|
"committerTip": "システムのデフォルトを使用する場合、空白のままにしてください",
|
||||||
|
@ -25,6 +25,8 @@ var storageModule;
|
|||||||
var settingsAvailable;
|
var settingsAvailable;
|
||||||
var sessionsAvailable;
|
var sessionsAvailable;
|
||||||
|
|
||||||
|
var libraryFlowsCachedResult = null;
|
||||||
|
|
||||||
function moduleSelector(aSettings) {
|
function moduleSelector(aSettings) {
|
||||||
var toReturn;
|
var toReturn;
|
||||||
if (aSettings.storageModule) {
|
if (aSettings.storageModule) {
|
||||||
@ -156,7 +158,14 @@ var storageModuleInterface = {
|
|||||||
if (storageModule.hasOwnProperty("getAllFlows")) {
|
if (storageModule.hasOwnProperty("getAllFlows")) {
|
||||||
return storageModule.getAllFlows();
|
return storageModule.getAllFlows();
|
||||||
} else {
|
} else {
|
||||||
return listFlows("/");
|
if (libraryFlowsCachedResult) {
|
||||||
|
return Promise.resolve(libraryFlowsCachedResult);
|
||||||
|
} else {
|
||||||
|
return listFlows("/").then(function(result) {
|
||||||
|
libraryFlowsCachedResult = result;
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getFlow: function(fn) {
|
getFlow: function(fn) {
|
||||||
@ -178,6 +187,7 @@ var storageModuleInterface = {
|
|||||||
err.code = "forbidden";
|
err.code = "forbidden";
|
||||||
return when.reject(err);
|
return when.reject(err);
|
||||||
}
|
}
|
||||||
|
libraryFlowsCachedResult = null;
|
||||||
if (storageModule.hasOwnProperty("saveFlow")) {
|
if (storageModule.hasOwnProperty("saveFlow")) {
|
||||||
return storageModule.saveFlow(fn, data);
|
return storageModule.saveFlow(fn, data);
|
||||||
} else {
|
} 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