diff --git a/editor/js/nodes.js b/editor/js/nodes.js index e3a906bf6..79a2ee413 100644 --- a/editor/js/nodes.js +++ b/editor/js/nodes.js @@ -115,6 +115,7 @@ RED.nodes = (function() { }, registerNodeType: function(nt,def) { nodeDefinitions[nt] = def; + def.type = nt; if (def.category != "subflows") { def.set = nodeSets[typeToId[nt]]; nodeSets[typeToId[nt]].added = true; diff --git a/editor/js/ui/diff.js b/editor/js/ui/diff.js index 553e73cd0..27e069ceb 100644 --- a/editor/js/ui/diff.js +++ b/editor/js/ui/diff.js @@ -342,21 +342,14 @@ RED.diff = (function() { function createNodeIcon(node,def) { var nodeDiv = $("
",{class:"node-diff-node-entry-node"}); var colour = def.color; - var icon_url = "arrow-in.png"; + var icon_url = RED.utils.getNodeIcon(def,node); if (node.type === 'tab') { colour = "#C0DEED"; - icon_url = "subflow.png"; - } else if (def.category === 'config') { - icon_url = "cog.png"; - } else if (node.type === 'unknown') { - icon_url = "alert.png"; - } else { - icon_url = def.icon; } nodeDiv.css('backgroundColor',colour); var iconContainer = $('
',{class:"palette_icon_container"}).appendTo(nodeDiv); - $('
',{class:"palette_icon",style:"background-image: url(icons/"+icon_url+")"}).appendTo(iconContainer); + $('
',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer); return nodeDiv; } diff --git a/editor/js/ui/palette.js b/editor/js/ui/palette.js index a13edabb4..90adb944a 100644 --- a/editor/js/ui/palette.js +++ b/editor/js/ui/palette.js @@ -149,14 +149,9 @@ RED.palette = (function() { if (def.icon) { - var icon_url = "arrow-in.png"; - try { - icon_url = (typeof def.icon === "function" ? def.icon.call({}) : def.icon); - } catch(err) { - console.log("Definition error: "+nt+".icon",err); - } + var icon_url = RED.utils.getNodeIcon(def); var iconContainer = $('
',{class:"palette_icon_container"+(def.align=="right"?" palette_icon_container_right":"")}).appendTo(d); - $('
',{class:"palette_icon",style:"background-image: url(icons/"+icon_url+")"}).appendTo(iconContainer); + $('
',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer); } d.style.backgroundColor = def.color; @@ -236,7 +231,7 @@ RED.palette = (function() { // it here makes me sad //console.log(ui.helper.position()); ui.position.left += 17.5; - + if (def.inputs > 0 && def.outputs > 0) { mouseX = ui.position.left+(ui.helper.width()/2) - chartOffset.left + chart.scrollLeft(); mouseY = ui.position.top+(ui.helper.height()/2) - chartOffset.top + chart.scrollTop(); diff --git a/editor/js/ui/search.js b/editor/js/ui/search.js index 464349623..18565fd13 100644 --- a/editor/js/ui/search.js +++ b/editor/js/ui/search.js @@ -189,25 +189,14 @@ RED.search = (function() { var nodeDiv = $('
',{class:"red-ui-search-result-node"}).appendTo(div); var colour = def.color; - var icon_url = "arrow-in.png"; + var icon_url = RED.utils.getNodeIcon(def,node); if (node.type === 'tab') { colour = "#C0DEED"; - icon_url = "subflow.png"; - } else if (def.category === 'config') { - icon_url = "cog.png"; - } else if (node.type === 'unknown') { - icon_url = "alert.png"; - } else { - try { - icon_url = (typeof def.icon === "function" ? def.icon.call({}) : def.icon); - } catch(err) { - console.log("Definition error: "+nt+".icon",err); - } } nodeDiv.css('backgroundColor',colour); var iconContainer = $('
',{class:"palette_icon_container"}).appendTo(nodeDiv); - $('
',{class:"palette_icon",style:"background-image: url(icons/"+icon_url+")"}).appendTo(iconContainer); + $('
',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer); var contentDiv = $('
',{class:"red-ui-search-result-description"}).appendTo(div); if (node.z) { diff --git a/editor/js/ui/typeSearch.js b/editor/js/ui/typeSearch.js index 6762811d4..66af2c117 100644 --- a/editor/js/ui/typeSearch.js +++ b/editor/js/ui/typeSearch.js @@ -110,20 +110,11 @@ RED.typeSearch = (function() { var nodeDiv = $('
',{class:"red-ui-search-result-node"}).appendTo(div); var colour = def.color; - var icon_url = "arrow-in.png"; - if (def.category === 'config') { - icon_url = "cog.png"; - } else { - try { - icon_url = (typeof def.icon === "function" ? def.icon.call({}) : def.icon); - } catch(err) { - console.log("Definition error: "+object.type+".icon",err); - } - } + var icon_url = RED.utils.getNodeIcon(def); nodeDiv.css('backgroundColor',colour); var iconContainer = $('
',{class:"palette_icon_container"}).appendTo(nodeDiv); - $('
',{class:"palette_icon",style:"background-image: url(icons/"+icon_url+")"}).appendTo(iconContainer); + $('
',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer); if (def.inputs > 0) { $('
',{class:"red-ui-search-result-node-port"}).appendTo(nodeDiv); diff --git a/editor/js/ui/utils.js b/editor/js/ui/utils.js index 83d4e16f9..0231fe38b 100644 --- a/editor/js/ui/utils.js +++ b/editor/js/ui/utils.js @@ -367,8 +367,31 @@ RED.utils = (function() { return true; } + function getNodeIcon(def,node) { + if (def.category === 'config') { + return "icons/node-red/cog.png" + } else if (node && node.type === 'tab') { + return "icons/node-red/subflow.png" + } else if (node && node.type === 'unknown') { + return "icons/node-red/alert.png" + } + var icon_url; + if (typeof def.icon === "function") { + try { + icon_url = def.icon.call(node); + } catch(err) { + console.log("Definition error: "+def.type+".icon",err); + icon_url = "arrow-in.png"; + } + } else { + icon_url = def.icon; + } + return "icons/"+def.set.module+"/"+icon_url; + } + return { createObjectElement: buildMessageElement, - validatePropertyExpression: validatePropertyExpression + validatePropertyExpression: validatePropertyExpression, + getNodeIcon: getNodeIcon } })(); diff --git a/editor/js/ui/view.js b/editor/js/ui/view.js index f94059d71..3c083f9df 100644 --- a/editor/js/ui/view.js +++ b/editor/js/ui/view.js @@ -1832,7 +1832,7 @@ RED.view = (function() { //node.append("rect").attr("class", "node-gradient-bottom").attr("rx", 6).attr("ry", 6).attr("height",30).attr("stroke","none").attr("fill","url(#gradient-bottom)").style("pointer-events","none"); if (d._def.icon) { - + var icon_url = RED.utils.getNodeIcon(d._def,d); var icon_group = node.append("g") .attr("class","node_icon_group") .attr("x",0).attr("y",0); @@ -1847,7 +1847,7 @@ RED.view = (function() { .attr("height",function(d){return Math.min(50,d.h-4);}); var icon = icon_group.append("image") - .attr("xlink:href","icons/"+d._def.icon) + .attr("xlink:href",icon_url) .attr("class","node_icon") .attr("x",0) .attr("width","30") @@ -1878,7 +1878,7 @@ RED.view = (function() { //} var img = new Image(); - img.src = "icons/"+d._def.icon; + img.src = icon_url; img.onload = function() { icon.attr("width",Math.min(img.width,30)); icon.attr("height",Math.min(img.height,30)); @@ -1915,8 +1915,10 @@ RED.view = (function() { //node.append("circle").attr({"class":"centerDot","cx":0,"cy":0,"r":5}); //node.append("path").attr("class","node_error").attr("d","M 3,-3 l 10,0 l -5,-8 z"); - node.append("image").attr("class","node_error hidden").attr("xlink:href","icons/node-error.png").attr("x",0).attr("y",-6).attr("width",10).attr("height",9); - node.append("image").attr("class","node_changed hidden").attr("xlink:href","icons/node-changed.png").attr("x",12).attr("y",-6).attr("width",10).attr("height",10); + + //TODO: these ought to be SVG + node.append("image").attr("class","node_error hidden").attr("xlink:href","icons/node-red/node-error.png").attr("x",0).attr("y",-6).attr("width",10).attr("height",9); + node.append("image").attr("class","node_changed hidden").attr("xlink:href","icons/node-red/node-changed.png").attr("x",12).attr("y",-6).attr("width",10).attr("height",10); }); node.each(function(d,i) { @@ -2032,21 +2034,11 @@ RED.view = (function() { if (d._def.icon) { icon = thisNode.select(".node_icon"); var current_url = icon.attr("xlink:href"); - var icon_url; - if (typeof d._def.icon == "function") { - try { - icon_url = d._def.icon.call(d); - } catch(err) { - console.log("icon",err); - icon_url = "arrow-in.png"; - } - } else { - icon_url = d._def.icon; - } - if ("icons/"+icon_url != current_url) { - icon.attr("xlink:href","icons/"+icon_url); + var new_url = RED.utils.getNodeIcon(d._def,d); + if (new_url !== current_url) { + icon.attr("xlink:href",new_url); var img = new Image(); - img.src = "icons/"+d._def.icon; + img.src = new_url; img.onload = function() { icon.attr("width",Math.min(img.width,30)); icon.attr("height",Math.min(img.height,30)); diff --git a/red/api/index.js b/red/api/index.js index 38a0f4f84..901c3cd9b 100644 --- a/red/api/index.js +++ b/red/api/index.js @@ -94,7 +94,7 @@ function init(_server,_runtime) { }); } editorApp.get("/",ensureRuntimeStarted,ui.ensureSlash,ui.editor); - editorApp.get("/icons/:icon",ui.icon); + editorApp.get("/icons/:module/:icon",ui.icon); theme.init(runtime); if (settings.editorTheme) { editorApp.use("/theme",theme.app()); diff --git a/red/api/ui.js b/red/api/ui.js index ad76b02e4..0a2140060 100644 --- a/red/api/ui.js +++ b/red/api/ui.js @@ -21,7 +21,9 @@ var theme = require("./theme"); var Mustache = require("mustache"); -var icon_paths = [path.resolve(__dirname + '/../../public/icons')]; +var icon_paths = { + "node-red":[path.resolve(__dirname + '/../../public/icons')] +}; var iconCache = {}; //TODO: create a default icon var defaultIcon = path.resolve(__dirname + '/../../public/icons/arrow-in.png'); @@ -29,7 +31,8 @@ var templateDir = path.resolve(__dirname+"/../../editor/templates"); var editorTemplate; function nodeIconDir(dir) { - icon_paths.push(path.resolve(dir)); + icon_paths[dir.name] = icon_paths[dir.name] || []; + icon_paths[dir.name].push(path.resolve(dir.path)); } module.exports = { @@ -54,18 +57,24 @@ module.exports = { } }, icon: function(req,res) { - if (iconCache[req.params.icon]) { - res.sendFile(iconCache[req.params.icon]); // if not found, express prints this to the console and serves 404 + var icon = req.params.icon; + var module = req.params.module; + var iconName = module+"/"+icon; + if (iconCache[iconName]) { + res.sendFile(iconCache[iconName]); // if not found, express prints this to the console and serves 404 } else { - for (var p=0;p