/**
* 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.
**/
RED.sidebar.info = (function() {
var content;
var panels;
var infoSection;
var propertiesPanelContent;
var propertiesPanelHeader;
var propertiesPanelHeaderIcon;
var propertiesPanelHeaderLabel;
var propertiesPanelHeaderReveal;
var propertiesPanelHeaderHelp;
var selectedObject;
var tipBox;
// TODO: remove this
var expandedSections = {
"property": false
};
function resizeStack() {
var h = $(content).parent().height();
panels.resize(h)
}
function init() {
content = document.createElement("div");
content.className = "red-ui-sidebar-info"
RED.actions.add("core:show-info-tab",show);
var stackContainer = $("
",{class:"red-ui-sidebar-info-stack"}).appendTo(content);
var outlinerPanel = $("
").css({
"overflow": "hidden",
"height": "calc(70%)"
}).appendTo(stackContainer);
var propertiesPanel = $("
").css({
"flex":"1 1 auto",
"overflow-y":"scroll",
}).appendTo(propertiesPanel);
panels = RED.panels.create({container: stackContainer})
panels.ratio(0.6);
RED.sidebar.info.outliner.build().appendTo(outlinerPanel);
RED.sidebar.addTab({
id: "info",
label: RED._("sidebar.info.label"),
name: RED._("sidebar.info.name"),
iconClass: "fa fa-info",
action:"core:show-info-tab",
content: content,
pinned: true,
enableOnEdit: true
});
$(window).on("resize", resizeStack);
$(window).on("focus", resizeStack);
// Tip Box
var tipContainer = $('').appendTo(content);
tipBox = $('').appendTo(tipContainer);
var tipButtons = $('').appendTo(tipContainer);
var tipRefresh = $('').appendTo(tipButtons);
tipRefresh.on("click", function(e) {
e.preventDefault();
tips.next();
})
var tipClose = $('').appendTo(tipButtons);
tipClose.on("click", function(e) {
e.preventDefault();
RED.actions.invoke("core:toggle-show-tips");
RED.notify(RED._("sidebar.info.showTips"));
});
if (tips.enabled()) {
tips.start();
} else {
tips.stop();
}
}
function show() {
RED.sidebar.show("info");
}
// TODO: DRY - projects.js
function addTargetToExternalLinks(el) {
$(el).find("a").each(function(el) {
var href = $(this).attr('href');
if (/^https?:/.test(href)) {
$(this).attr('target','_blank');
}
});
return el;
}
function refresh(node) {
if (node === undefined) {
refreshSelection();
return;
}
$(propertiesPanelContent).empty();
var propRow;
var table = $('
').appendTo(propertiesPanelContent);
var tableBody = $('').appendTo(table);
var subflowNode;
var subflowUserCount;
if (node === null) {
return;
} else if (Array.isArray(node)) {
// Multiple things selected
// - hide help and info sections
propertiesPanelHeaderIcon.empty();
RED.utils.createNodeIcon({type:"_selection_"}).appendTo(propertiesPanelHeaderIcon);
propertiesPanelHeaderLabel.text("Selection");
propertiesPanelHeaderReveal.hide();
propertiesPanelHeaderHelp.hide();
selectedObject = null;
var types = {
nodes:0,
flows:0,
subflows:0,
groups: 0
}
node.forEach(function(n) {
if (n.type === 'tab') {
types.flows++;
types.nodes += RED.nodes.filterNodes({z:n.id}).length;
} else if (n.type === 'subflow') {
types.subflows++;
} else if (n.type === 'group') {
types.groups++;
} else {
types.nodes++;
}
});
// infoSection.container.hide();
// - show the count of selected nodes
propRow = $('
'+RED._("sidebar.info.selection")+"
").appendTo(tableBody);
var counts = $('
').appendTo($(propRow.children()[1]));
if (types.flows > 0) {
$('
').text(RED._("clipboard.flow",{count:types.flows})).appendTo(counts);
}
if (types.subflows > 0) {
$('
').text(RED._("clipboard.subflow",{count:types.subflows})).appendTo(counts);
}
if (types.nodes > 0) {
$('
').text(RED._("clipboard.node",{count:types.nodes})).appendTo(counts);
}
if (types.groups > 0) {
$('
').text(RED._("clipboard.group",{count:types.groups})).appendTo(counts);
}
} else {
// A single 'thing' selected.
// Check to see if this is a subflow or subflow instance
var subflowRegex = /^subflow(:(.+))?$/.exec(node.type);
if (subflowRegex) {
if (subflowRegex[2]) {
subflowNode = RED.nodes.subflow(subflowRegex[2]);
} else {
subflowNode = node;
}
subflowUserCount = 0;
var subflowType = "subflow:"+subflowNode.id;
RED.nodes.eachNode(function(n) {
if (n.type === subflowType) {
subflowUserCount++;
}
});
}
propertiesPanelHeaderIcon.empty();
RED.utils.createNodeIcon(node).appendTo(propertiesPanelHeaderIcon);
propertiesPanelHeaderLabel.text(RED.utils.getNodeLabel(node, node.type+" "+node.id));
propertiesPanelHeaderReveal.show();
selectedObject = node;
if (node.type === "tab" || node.type === "subflow") {
// If nothing is selected, but we're on a flow or subflow tab.
propertiesPanelHeaderHelp.hide();
} else if (node.type === "group") {
propertiesPanelHeaderHelp.hide();
propRow = $('
'+RED._("sidebar.info.group")+'
').appendTo(tableBody);
var typeCounts = {
nodes:0,
groups: 0
}
var allNodes = RED.group.getNodes(node,true);
allNodes.forEach(function(n) {
if (n.type === "group") {
typeCounts.groups++;
} else {
typeCounts.nodes++
}
});
var counts = $('
').appendTo($(propRow.children()[1]));
if (typeCounts.nodes > 0) {
$('
').text(RED._("clipboard.node",{count:typeCounts.nodes})).appendTo(counts);
}
if (typeCounts.groups > 0) {
$('
').appendTo(tableBody);
if (!subflowRegex) {
$(propRow.children()[0]).text(RED._("sidebar.info.node"))
} else {
$(propRow.children()[0]).text(RED._("sidebar.info.subflow"))
}
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
if (!subflowRegex) {
propRow = $('
'+RED._("sidebar.info.type")+'
').appendTo(tableBody);
$(propRow.children()[1]).text((node.type === "unknown")?node._orig.type:node.type);
if (node.type === "unknown") {
$('').prependTo($(propRow.children()[1]))
}
}
var count = 0;
if (!subflowRegex && node.type != "subflow" && node.type != "group") {
var blankRow = $('
').appendTo(tableBody);
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;
propRow = $('
'+RED._("sidebar.info.module")+"
").appendTo(tableBody);
$(propRow.children()[1]).text(RED.nodes.getType(node.type).set.module);
count++;
}
if (defaults) {
for (var n in defaults) {
if (n != "name" && n != "info" && defaults.hasOwnProperty(n)) {
var val = node[n];
var type = typeof val;
count++;
propRow = $('
').appendTo(tableBody);
$(propRow.children()[0]).text(n);
if (defaults[n].type) {
var configNode = RED.nodes.node(val);
if (!configNode) {
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
} else {
var configLabel = RED.utils.getNodeLabel(configNode,val);
var container = propRow.children()[1];
var div = $('',{class:""}).appendTo(container);
var nodeDiv = $('
',{class:"red-ui-palette-node red-ui-palette-node-small"}).appendTo(div);
var colour = RED.utils.getNodeColor(configNode.type,configNode._def);
var icon_url = RED.utils.getNodeIcon(configNode._def);
nodeDiv.css({'backgroundColor':colour, "cursor":"pointer"});
var iconContainer = $('',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
$('',{class:"red-ui-palette-icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer);
var nodeContainer = $('').css({"verticalAlign":"top","marginLeft":"6px"}).text(configLabel).appendTo(container);
nodeDiv.on('dblclick',function() {
RED.editor.editConfig("", configNode.type, configNode.id);
})
}
} else {
RED.utils.createObjectElement(val).appendTo(propRow.children()[1]);
}
}
}
}
if (count > 0) {
$(''+RED._("sidebar.info.showMore")+''+RED._("sidebar.info.showLess")+'').appendTo(blankRow.children()[0]);
}
}
if (node.type !== 'tab') {
if (subflowRegex) {
$('
'+RED._("sidebar.info.subflow")+'
').appendTo(tableBody);
$('
'+RED._("common.label.name")+'
'+RED.utils.sanitize(subflowNode.name)+'
').appendTo(tableBody);
}
}
}
if (subflowRegex) {
propRow = $('
'+RED._("subflow.category")+'
').appendTo(tableBody);
var category = subflowNode.category||"subflows";
$(propRow.children()[1]).text(RED._("palette.label."+category,{defaultValue:category}))
$('
'+RED._("sidebar.info.instances")+"
"+subflowUserCount+'
').appendTo(tableBody);
}
// var helpText = "";
// if (node.type === "tab" || node.type === "subflow") {
// } else {
// if (subflowNode && node.type !== "subflow") {
// // Selected a subflow instance node.
// // - The subflow template info goes into help
// helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||(''+RED._("sidebar.info.none")+''));
// } else {
// helpText = $("script[data-help-name='"+node.type+"']").html()||(''+RED._("sidebar.info.none")+'');
// }
// setInfoText(helpText, helpSection.content);
// }
var infoText = "";
if (node._def && node._def.info) {
var info = node._def.info;
var textInfo = (typeof info === "function" ? info.call(node) : info);
infoText = infoText + RED.utils.renderMarkdown(textInfo);
}
if (node.info) {
infoText = infoText + RED.utils.renderMarkdown(node.info || "")
}
var infoSectionContainer = $("