2016-11-03 00:20:48 +01:00
|
|
|
/**
|
2017-01-11 16:24:33 +01:00
|
|
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
2016-11-03 00:20:48 +01:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
**/
|
|
|
|
|
2016-10-27 09:48:32 +02:00
|
|
|
if (!RED) {
|
|
|
|
var RED = {}
|
|
|
|
}
|
2016-10-24 17:53:09 +02:00
|
|
|
RED.debug = (function() {
|
2016-10-27 00:20:43 +02:00
|
|
|
var config;
|
|
|
|
var messageList;
|
|
|
|
var messageTable;
|
2017-05-22 12:35:45 +02:00
|
|
|
var filterType = "filterAll";
|
|
|
|
var filteredNodes = {}; // id->true means hide, so default to all visible
|
|
|
|
|
2016-10-27 00:20:43 +02:00
|
|
|
var view = 'list';
|
|
|
|
var messages = [];
|
|
|
|
var messagesByNode = {};
|
|
|
|
var sbc;
|
|
|
|
var activeWorkspace;
|
2017-10-10 22:53:25 +02:00
|
|
|
var numMessages = 100; // Hardcoded number of message to show in debug window scrollback
|
2016-10-27 00:20:43 +02:00
|
|
|
|
2017-05-22 12:35:45 +02:00
|
|
|
var filterVisible = false;
|
|
|
|
|
|
|
|
var debugNodeList;
|
|
|
|
var debugNodeListExpandedFlows = {};
|
|
|
|
|
2016-10-27 00:20:43 +02:00
|
|
|
function init(_config) {
|
|
|
|
config = _config;
|
|
|
|
|
|
|
|
var content = $("<div>").css({"position":"relative","height":"100%"});
|
2019-04-30 23:56:39 +02:00
|
|
|
var toolbar = $('<div class="red-ui-sidebar-header">'+
|
2019-05-08 14:26:48 +02:00
|
|
|
'<span class="button-group"><a id="red-ui-sidebar-debug-filter" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span></a></span>'+
|
2019-08-06 17:10:33 +02:00
|
|
|
'<span class="button-group"><a id="red-ui-sidebar-debug-clear" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-trash"></i></a></span></div>').appendTo(content);
|
2016-10-27 00:20:43 +02:00
|
|
|
|
|
|
|
var footerToolbar = $('<div>'+
|
|
|
|
// '<span class="button-group">'+
|
2019-05-08 14:26:48 +02:00
|
|
|
// '<a class="red-ui-footer-button-toggle text-button selected" id="red-ui-sidebar-debug-view-list" href="#"><span data-i18n="">list</span></a>'+
|
|
|
|
// '<a class="red-ui-footer-button-toggle text-button" id="red-ui-sidebar-debug-view-table" href="#"><span data-i18n="">table</span></a> '+
|
2016-10-27 00:20:43 +02:00
|
|
|
// '</span>'+
|
2019-08-06 17:10:33 +02:00
|
|
|
'<span class="button-group"><a id="red-ui-sidebar-debug-open" class="red-ui-footer-button" href="#"><i class="fa fa-desktop"></i></a></span> ' +
|
2016-10-27 00:20:43 +02:00
|
|
|
'</div>');
|
|
|
|
|
2019-05-16 14:43:42 +02:00
|
|
|
messageList = $('<div class="red-ui-debug-content red-ui-debug-content-list"/>').appendTo(content);
|
2016-10-27 00:20:43 +02:00
|
|
|
sbc = messageList[0];
|
2019-05-16 14:43:42 +02:00
|
|
|
messageTable = $('<div class="red-ui-debug-content red-ui-debug-content-table hide"/>').appendTo(content);
|
2016-10-27 00:20:43 +02:00
|
|
|
|
2019-05-02 23:33:29 +02:00
|
|
|
var filterDialog = $('<div class="red-ui-debug-filter-box hide">'+
|
|
|
|
'<div class="red-ui-debug-filter-row">'+
|
2016-10-27 00:20:43 +02:00
|
|
|
'<span class="button-group">'+
|
2019-05-08 14:26:48 +02:00
|
|
|
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option selected" id="red-ui-sidebar-debug-filterAll" href="#"><span data-i18n="node-red:debug.sidebar.filterAll"></span></a>'+
|
|
|
|
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterSelected" href="#"><span data-i18n="node-red:debug.sidebar.filterSelected"></span></a>'+
|
|
|
|
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterCurrent" href="#"><span data-i18n="node-red:debug.sidebar.filterCurrent"></span></a> '+
|
2016-10-27 00:20:43 +02:00
|
|
|
'</span>'+
|
|
|
|
'</div>'+
|
2017-05-22 12:35:45 +02:00
|
|
|
'</div>').appendTo(toolbar);//content);
|
|
|
|
|
2019-05-02 23:33:29 +02:00
|
|
|
// var filterTypeRow = $('<div class="red-ui-debug-filter-row"></div>').appendTo(filterDialog);
|
2017-05-22 12:35:45 +02:00
|
|
|
// $('<select><option>Show all debug nodes</option><option>Show selected debug nodes</option><option>Show current flow only</option></select>').appendTo(filterTypeRow);
|
|
|
|
|
2019-05-16 23:32:28 +02:00
|
|
|
var debugNodeListRow = $('<div class="red-ui-debug-filter-row hide" id="red-ui-sidebar-debug-filter-node-list-row"></div>').appendTo(filterDialog);
|
2017-05-22 12:35:45 +02:00
|
|
|
var flowCheckboxes = {};
|
2017-07-19 14:50:34 +02:00
|
|
|
var debugNodeListHeader = $('<div><span data-i18n="node-red:debug.sidebar.debugNodes"></span><span></span></div>');
|
2017-05-22 12:35:45 +02:00
|
|
|
var headerCheckbox = $('<input type="checkbox">').appendTo(debugNodeListHeader.find("span")[1]).checkboxSet();
|
|
|
|
|
|
|
|
debugNodeList = $('<ol>',{style:"text-align: left; min-height: 250px; max-height: 250px"}).appendTo(debugNodeListRow).editableList({
|
|
|
|
header: debugNodeListHeader,
|
|
|
|
class: 'red-ui-nodeList',
|
|
|
|
addItem: function(container,i,node) {
|
|
|
|
var row = $("<div>").appendTo(container);
|
|
|
|
row.attr('id','debug-filter-node-list-node-'+node.id.replace(/\./g,"_"));
|
|
|
|
if (node.type === 'tab') {
|
|
|
|
container.parent().addClass('red-ui-editableList-section-header');
|
|
|
|
if (!debugNodeListExpandedFlows.hasOwnProperty(node.id)) {
|
|
|
|
debugNodeListExpandedFlows[node.id] = true;
|
|
|
|
}
|
|
|
|
var chevron = $('<i class="fa fa-angle-right"></i>').appendTo(row);
|
|
|
|
$('<span>').text(RED.utils.getNodeLabel(node,node.id)).appendTo(row);
|
|
|
|
var muteControl = $('<input type="checkbox">').appendTo($('<span class="meta">').appendTo(row));
|
|
|
|
muteControl.checkboxSet({
|
|
|
|
parent: headerCheckbox
|
|
|
|
});
|
|
|
|
flowCheckboxes[node.id] = muteControl;
|
2019-04-29 12:50:15 +02:00
|
|
|
row.on("click", function(e) {
|
2017-05-22 12:35:45 +02:00
|
|
|
e.stopPropagation();
|
|
|
|
debugNodeListExpandedFlows[node.id] = !debugNodeListExpandedFlows[node.id];
|
|
|
|
row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]);
|
|
|
|
debugNodeList.editableList('filter');
|
|
|
|
})
|
|
|
|
row.addClass("expandable");
|
|
|
|
if (node.disabled) {
|
|
|
|
container.addClass('disabled');
|
|
|
|
muteControl.checkboxSet('disable');
|
|
|
|
debugNodeListExpandedFlows[node.id] = false;
|
|
|
|
}
|
|
|
|
row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]);
|
|
|
|
} else {
|
|
|
|
$('<span>',{style: "margin-left: 20px"}).text(RED.utils.getNodeLabel(node,node.id)).appendTo(row);
|
|
|
|
row.on("mouseenter",function() {
|
|
|
|
config.messageMouseEnter(node.id);
|
|
|
|
});
|
|
|
|
row.on("mouseleave",function() {
|
|
|
|
config.messageMouseLeave(node.id);
|
|
|
|
});
|
|
|
|
var muteControl = $('<input type="checkbox">').prop('checked',!filteredNodes[node.id]).appendTo($('<span class="meta">').appendTo(row));
|
|
|
|
muteControl.checkboxSet({
|
|
|
|
parent: flowCheckboxes[node.z]
|
2019-04-29 12:50:15 +02:00
|
|
|
}).on("change", function(e) {
|
2017-05-22 12:35:45 +02:00
|
|
|
filteredNodes[node.id] = !$(this).prop('checked');
|
2019-05-02 23:33:29 +02:00
|
|
|
$(".red-ui-debug-msg-node-"+node.id.replace(/\./g,"_")).toggleClass('hide',filteredNodes[node.id]);
|
2017-05-22 12:35:45 +02:00
|
|
|
});
|
2021-02-10 09:32:27 +01:00
|
|
|
if ((node.hasOwnProperty("active") && !node.active) || RED.nodes.workspace(node.z).disabled) {
|
2017-05-22 12:35:45 +02:00
|
|
|
container.addClass('disabled');
|
|
|
|
muteControl.checkboxSet('disable');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
addButton: false,
|
|
|
|
scrollOnAdd: false,
|
|
|
|
filter: function(node) {
|
|
|
|
return (node.type === 'tab' || debugNodeListExpandedFlows[node.z] )
|
|
|
|
},
|
|
|
|
sort: function(A,B) {
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
2016-10-27 00:20:43 +02:00
|
|
|
|
2016-10-27 09:48:32 +02:00
|
|
|
try {
|
|
|
|
content.i18n();
|
|
|
|
} catch(err) {
|
|
|
|
console.log("TODO: i18n library support");
|
|
|
|
}
|
2016-10-27 00:20:43 +02:00
|
|
|
|
2019-05-08 14:26:48 +02:00
|
|
|
toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll'));
|
2016-10-27 00:20:43 +02:00
|
|
|
|
2017-05-22 12:35:45 +02:00
|
|
|
var filterButtonHandler = function(type) {
|
|
|
|
return function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
if (filterType !== type) {
|
2019-05-08 14:26:48 +02:00
|
|
|
$('.red-ui-sidebar-debug-filter-option').removeClass('selected');
|
2017-05-22 12:35:45 +02:00
|
|
|
$(this).addClass('selected');
|
|
|
|
if (filterType === 'filterSelected') {
|
|
|
|
debugNodeListRow.slideUp();
|
|
|
|
}
|
|
|
|
filterType = type;
|
|
|
|
if (filterType === 'filterSelected') {
|
|
|
|
debugNodeListRow.slideDown();
|
|
|
|
}
|
|
|
|
|
2019-05-08 14:26:48 +02:00
|
|
|
$('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType));
|
2017-05-22 12:35:45 +02:00
|
|
|
refreshMessageList();
|
|
|
|
}
|
2016-10-27 00:20:43 +02:00
|
|
|
}
|
2017-05-22 12:35:45 +02:00
|
|
|
}
|
2019-05-08 14:26:48 +02:00
|
|
|
filterDialog.find('#red-ui-sidebar-debug-filterAll').on("click",filterButtonHandler('filterAll'));
|
|
|
|
filterDialog.find('#red-ui-sidebar-debug-filterSelected').on("click",filterButtonHandler('filterSelected'));
|
|
|
|
filterDialog.find('#red-ui-sidebar-debug-filterCurrent').on("click",filterButtonHandler('filterCurrent'));
|
2017-05-22 12:35:45 +02:00
|
|
|
|
|
|
|
|
2019-05-08 14:26:48 +02:00
|
|
|
// $('#red-ui-sidebar-debug-view-list').on("click",function(e) {
|
2016-10-27 00:20:43 +02:00
|
|
|
// e.preventDefault();
|
|
|
|
// if (!$(this).hasClass('selected')) {
|
|
|
|
// $(this).addClass('selected');
|
2019-05-08 14:26:48 +02:00
|
|
|
// $('#red-ui-sidebar-debug-view-table').removeClass('selected');
|
2016-10-27 00:20:43 +02:00
|
|
|
// showMessageList();
|
|
|
|
// }
|
|
|
|
// });
|
2019-05-08 14:26:48 +02:00
|
|
|
// $('#red-ui-sidebar-debug-view-table').on("click",function(e) {
|
2016-10-27 00:20:43 +02:00
|
|
|
// e.preventDefault();
|
|
|
|
// if (!$(this).hasClass('selected')) {
|
|
|
|
// $(this).addClass('selected');
|
2019-05-08 14:26:48 +02:00
|
|
|
// $('#red-ui-sidebar-debug-view-list').removeClass('selected');
|
2016-10-27 00:20:43 +02:00
|
|
|
// showMessageTable();
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
2017-05-22 12:35:45 +02:00
|
|
|
var hideFilterTimeout;
|
|
|
|
toolbar.on('mouseleave',function() {
|
2019-05-08 14:26:48 +02:00
|
|
|
if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) {
|
2017-05-22 12:35:45 +02:00
|
|
|
clearTimeout(hideFilterTimeout);
|
|
|
|
hideFilterTimeout = setTimeout(function() {
|
|
|
|
filterVisible = false;
|
2019-05-08 14:26:48 +02:00
|
|
|
$('#red-ui-sidebar-debug-filter').removeClass('selected');
|
2017-05-22 12:35:45 +02:00
|
|
|
filterDialog.slideUp(200);
|
|
|
|
},300);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
toolbar.on('mouseenter',function() {
|
2019-05-08 14:26:48 +02:00
|
|
|
if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) {
|
2017-05-22 12:35:45 +02:00
|
|
|
clearTimeout(hideFilterTimeout);
|
|
|
|
}
|
|
|
|
})
|
2019-05-08 14:26:48 +02:00
|
|
|
toolbar.find('#red-ui-sidebar-debug-filter').on("click",function(e) {
|
2016-10-27 00:20:43 +02:00
|
|
|
e.preventDefault();
|
|
|
|
if ($(this).hasClass('selected')) {
|
2017-05-22 12:35:45 +02:00
|
|
|
filterVisible = false;
|
2016-10-27 00:20:43 +02:00
|
|
|
$(this).removeClass('selected');
|
2017-05-22 12:35:45 +02:00
|
|
|
clearTimeout(hideFilterTimeout);
|
2016-10-27 00:20:43 +02:00
|
|
|
filterDialog.slideUp(200);
|
|
|
|
} else {
|
|
|
|
$(this).addClass('selected');
|
2017-05-22 12:35:45 +02:00
|
|
|
filterVisible = true;
|
|
|
|
refreshDebugNodeList();
|
2016-10-27 00:20:43 +02:00
|
|
|
filterDialog.slideDown(200);
|
|
|
|
}
|
2018-10-24 23:57:16 +02:00
|
|
|
});
|
2019-05-08 14:26:48 +02:00
|
|
|
RED.popover.tooltip(toolbar.find('#red-ui-sidebar-debug-filter'),RED._('node-red:debug.sidebar.filterLog'));
|
2016-10-27 00:20:43 +02:00
|
|
|
|
2019-05-08 14:26:48 +02:00
|
|
|
toolbar.find("#red-ui-sidebar-debug-clear").on("click", function(e) {
|
2016-10-27 00:20:43 +02:00
|
|
|
e.preventDefault();
|
2018-01-05 17:13:02 +01:00
|
|
|
clearMessageList(false);
|
2016-10-27 00:20:43 +02:00
|
|
|
});
|
2019-09-23 11:24:23 +02:00
|
|
|
RED.popover.tooltip(toolbar.find("#red-ui-sidebar-debug-clear"),RED._('node-red:debug.sidebar.clearLog'),"core:clear-debug-messages");
|
2018-10-05 18:56:42 +02:00
|
|
|
|
2016-10-27 00:20:43 +02:00
|
|
|
return {
|
|
|
|
content: content,
|
|
|
|
footer: footerToolbar
|
2021-02-19 06:35:59 +01:00
|
|
|
};
|
2016-10-27 00:20:43 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-02-19 06:35:59 +01:00
|
|
|
|
2021-02-10 09:32:27 +01:00
|
|
|
function containsDebug(sid, map) {
|
2021-02-19 06:35:59 +01:00
|
|
|
var item = map[sid];
|
|
|
|
if (item) {
|
|
|
|
if (item.debug === undefined) {
|
|
|
|
var sfs = Object.keys(item.subflows);
|
|
|
|
var contain = false;
|
|
|
|
for (var i = 0; i < sfs.length; i++) {
|
|
|
|
var sf = sfs[i];
|
|
|
|
if (containsDebug(sf, map)) {
|
|
|
|
contain = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-02-10 09:32:27 +01:00
|
|
|
}
|
2021-02-19 06:35:59 +01:00
|
|
|
item.debug = contain;
|
2021-02-10 09:32:27 +01:00
|
|
|
}
|
2021-02-19 06:35:59 +01:00
|
|
|
return item.debug;
|
2021-02-10 09:32:27 +01:00
|
|
|
}
|
2021-02-19 06:35:59 +01:00
|
|
|
return false;
|
2021-02-10 09:32:27 +01:00
|
|
|
}
|
|
|
|
|
2021-02-19 06:35:59 +01:00
|
|
|
|
2017-05-22 12:35:45 +02:00
|
|
|
function refreshDebugNodeList() {
|
|
|
|
debugNodeList.editableList('empty');
|
2021-02-19 06:35:59 +01:00
|
|
|
|
2017-05-22 12:35:45 +02:00
|
|
|
var workspaceOrder = RED.nodes.getWorkspaceOrder();
|
|
|
|
var workspaceOrderMap = {};
|
|
|
|
workspaceOrder.forEach(function(ws,i) {
|
|
|
|
workspaceOrderMap[ws] = i;
|
|
|
|
});
|
2021-02-19 06:35:59 +01:00
|
|
|
|
|
|
|
var candidateNodes = [];
|
|
|
|
var candidateSFs = [];
|
|
|
|
var subflows = {};
|
2021-02-10 09:32:27 +01:00
|
|
|
RED.nodes.eachNode(function (n) {
|
|
|
|
var nt = n.type;
|
2021-02-19 06:35:59 +01:00
|
|
|
if (nt === "debug") {
|
|
|
|
if (n.z in workspaceOrderMap) {
|
2021-02-10 09:32:27 +01:00
|
|
|
candidateNodes.push(n);
|
|
|
|
}
|
2021-02-19 06:35:59 +01:00
|
|
|
else {
|
|
|
|
var sf = RED.nodes.subflow(n.z);
|
|
|
|
if (sf) {
|
|
|
|
subflows[sf.id] = {
|
|
|
|
debug: true,
|
|
|
|
subflows: {}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(nt.substring(0, 8) === "subflow:") {
|
|
|
|
if (n.z in workspaceOrderMap) {
|
|
|
|
candidateSFs.push(n);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
var psf = RED.nodes.subflow(n.z);
|
|
|
|
if (psf) {
|
|
|
|
var sid = nt.substring(8);
|
|
|
|
var item = subflows[psf.id];
|
|
|
|
if (!item) {
|
|
|
|
item = {
|
|
|
|
debug: undefined,
|
|
|
|
subflows: {}
|
|
|
|
};
|
|
|
|
subflows[psf.id] = item;
|
|
|
|
}
|
|
|
|
item.subflows[sid] = true;
|
|
|
|
}
|
|
|
|
}
|
2021-02-10 09:32:27 +01:00
|
|
|
}
|
|
|
|
});
|
2021-02-19 06:35:59 +01:00
|
|
|
candidateSFs.forEach(function (sf) {
|
|
|
|
var sid = sf.type.substring(8);
|
|
|
|
if (containsDebug(sid, subflows)) {
|
|
|
|
candidateNodes.push(sf);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-05-22 12:35:45 +02:00
|
|
|
candidateNodes.sort(function(A,B) {
|
|
|
|
var wsA = workspaceOrderMap[A.z];
|
|
|
|
var wsB = workspaceOrderMap[B.z];
|
|
|
|
if (wsA !== wsB) {
|
|
|
|
return wsA-wsB;
|
|
|
|
}
|
|
|
|
var labelA = RED.utils.getNodeLabel(A,A.id);
|
|
|
|
var labelB = RED.utils.getNodeLabel(B,B.id);
|
|
|
|
return labelA.localeCompare(labelB);
|
2021-02-10 09:32:27 +01:00
|
|
|
});
|
2017-05-22 12:35:45 +02:00
|
|
|
var currentWs = null;
|
|
|
|
var nodeList = [];
|
|
|
|
candidateNodes.forEach(function(node) {
|
|
|
|
if (currentWs !== node.z) {
|
|
|
|
currentWs = node.z;
|
|
|
|
nodeList.push(RED.nodes.workspace(node.z));
|
|
|
|
}
|
|
|
|
nodeList.push(node);
|
2021-02-10 09:32:27 +01:00
|
|
|
});
|
|
|
|
debugNodeList.editableList('addItems',nodeList);
|
2017-05-22 12:35:45 +02:00
|
|
|
}
|
|
|
|
|
2016-10-27 00:20:43 +02:00
|
|
|
function getTimestamp() {
|
|
|
|
var d = new Date();
|
|
|
|
return d.toLocaleString();
|
|
|
|
}
|
|
|
|
|
|
|
|
function sanitize(m) {
|
|
|
|
return m.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
|
|
|
}
|
|
|
|
|
|
|
|
function refreshMessageList(_activeWorkspace) {
|
|
|
|
if (_activeWorkspace) {
|
2017-05-22 12:35:45 +02:00
|
|
|
activeWorkspace = _activeWorkspace.replace(/\./g,"_");
|
|
|
|
}
|
|
|
|
if (filterType === "filterAll") {
|
2019-05-02 23:33:29 +02:00
|
|
|
$(".red-ui-debug-msg").removeClass("hide");
|
2017-05-22 12:35:45 +02:00
|
|
|
} else {
|
2019-05-02 23:33:29 +02:00
|
|
|
$(".red-ui-debug-msg").each(function() {
|
2017-05-22 12:35:45 +02:00
|
|
|
if (filterType === 'filterCurrent') {
|
2019-05-02 23:33:29 +02:00
|
|
|
$(this).toggleClass('hide',!$(this).hasClass('red-ui-debug-msg-flow-'+activeWorkspace));
|
2017-05-22 12:35:45 +02:00
|
|
|
} else if (filterType === 'filterSelected') {
|
|
|
|
var id = $(this).data('source');
|
|
|
|
if (id) {
|
|
|
|
$(this).toggleClass('hide',!!filteredNodes[id]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2016-10-27 00:20:43 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
function refreshMessageTable() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function showMessageList() {
|
|
|
|
view = 'list';
|
|
|
|
messageTable.hide();
|
|
|
|
messageTable.empty();
|
|
|
|
|
|
|
|
messages.forEach(function(m) {
|
|
|
|
messageList.append(m.el);
|
|
|
|
})
|
|
|
|
messageList.show();
|
|
|
|
}
|
|
|
|
function showMessageTable() {
|
|
|
|
view = 'table';
|
|
|
|
messageList.hide();
|
|
|
|
messageList.empty();
|
|
|
|
|
|
|
|
Object.keys(messagesByNode).forEach(function(id) {
|
|
|
|
var m = messagesByNode[id];
|
|
|
|
var msg = m.el;
|
|
|
|
var sourceNode = m.source;
|
|
|
|
if (sourceNode) {
|
2019-05-02 23:33:29 +02:00
|
|
|
var wrapper = $("<div>",{id:"red-ui-debug-msg-source-"+sourceNode.id.replace(/\./g,"_")}).appendTo(messageTable);
|
2016-10-27 00:20:43 +02:00
|
|
|
wrapper.append(msg);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
messageTable.show();
|
|
|
|
}
|
2016-10-27 23:12:07 +02:00
|
|
|
function formatString(str) {
|
|
|
|
return str.replace(/\n/g,"↵").replace(/\t/g,"→");
|
|
|
|
}
|
2016-10-27 00:20:43 +02:00
|
|
|
|
2017-05-12 23:12:55 +02:00
|
|
|
|
|
|
|
var menuOptionMenu;
|
|
|
|
var activeMenuMessage;
|
|
|
|
function showMessageMenu(button,dbgMessage,sourceId) {
|
|
|
|
activeMenuMessage = dbgMessage;
|
|
|
|
if (!menuOptionMenu) {
|
2019-05-02 23:33:29 +02:00
|
|
|
menuOptionMenu = RED.menu.init({id:"red-ui-debug-msg-option-menu",
|
2017-05-12 23:12:55 +02:00
|
|
|
options: [
|
2019-05-02 23:33:29 +02:00
|
|
|
{id:"red-ui-debug-msg-menu-item-collapse",label:RED._("node-red:debug.messageMenu.collapseAll"),onselect:function(){
|
2017-05-12 23:12:55 +02:00
|
|
|
activeMenuMessage.collapse();
|
|
|
|
}},
|
2019-05-02 23:33:29 +02:00
|
|
|
{id:"red-ui-debug-msg-menu-item-clear-pins",label:RED._("node-red:debug.messageMenu.clearPinned"),onselect:function(){
|
2017-05-12 23:12:55 +02:00
|
|
|
activeMenuMessage.clearPinned();
|
2017-05-22 12:35:45 +02:00
|
|
|
}},
|
|
|
|
null,
|
2019-05-02 23:33:29 +02:00
|
|
|
{id:"red-ui-debug-msg-menu-item-filter", label:RED._("node-red:debug.messageMenu.filterNode"),onselect:function(){
|
2017-05-22 12:35:45 +02:00
|
|
|
var candidateNodes = RED.nodes.filterNodes({type:'debug'});
|
|
|
|
candidateNodes.forEach(function(n) {
|
|
|
|
filteredNodes[n.id] = true;
|
|
|
|
});
|
|
|
|
delete filteredNodes[sourceId];
|
2019-05-08 14:26:48 +02:00
|
|
|
$("#red-ui-sidebar-debug-filterSelected").trigger("click");
|
2017-05-22 12:35:45 +02:00
|
|
|
refreshMessageList();
|
|
|
|
}},
|
2019-05-02 23:33:29 +02:00
|
|
|
{id:"red-ui-debug-msg-menu-item-clear-filter",label:RED._("node-red:debug.messageMenu.clearFilter"),onselect:function(){
|
2019-05-08 14:26:48 +02:00
|
|
|
$("#red-ui-sidebar-debug-filterAll").trigger("click");
|
2017-05-22 12:35:45 +02:00
|
|
|
refreshMessageList();
|
2017-05-12 23:12:55 +02:00
|
|
|
}}
|
|
|
|
]
|
|
|
|
});
|
|
|
|
menuOptionMenu.css({
|
|
|
|
position: "absolute"
|
|
|
|
})
|
|
|
|
menuOptionMenu.on('mouseleave', function(){ $(this).hide() });
|
|
|
|
menuOptionMenu.on('mouseup', function() { $(this).hide() });
|
|
|
|
menuOptionMenu.appendTo("body");
|
|
|
|
}
|
2018-03-03 23:41:02 +01:00
|
|
|
|
|
|
|
var filterOptionDisabled = false;
|
|
|
|
var sourceNode = RED.nodes.node(sourceId);
|
|
|
|
if (sourceNode && sourceNode.type !== 'debug') {
|
|
|
|
filterOptionDisabled = true;
|
|
|
|
}
|
2019-05-02 23:33:29 +02:00
|
|
|
RED.menu.setDisabled('red-ui-debug-msg-menu-item-filter',filterOptionDisabled);
|
|
|
|
RED.menu.setDisabled('red-ui-debug-msg-menu-item-clear-filter',filterOptionDisabled);
|
2018-03-03 23:41:02 +01:00
|
|
|
|
2017-05-12 23:12:55 +02:00
|
|
|
var elementPos = button.offset();
|
|
|
|
menuOptionMenu.css({
|
|
|
|
top: elementPos.top+"px",
|
|
|
|
left: (elementPos.left - menuOptionMenu.width() + 20)+"px"
|
|
|
|
})
|
|
|
|
menuOptionMenu.show();
|
|
|
|
}
|
2017-10-10 22:53:25 +02:00
|
|
|
|
|
|
|
var stack = [];
|
|
|
|
var busy = false;
|
2016-10-27 00:20:43 +02:00
|
|
|
function handleDebugMessage(o) {
|
2017-10-10 22:53:25 +02:00
|
|
|
if (o) { stack.push(o); }
|
|
|
|
if (!busy && (stack.length > 0)) {
|
|
|
|
busy = true;
|
|
|
|
processDebugMessage(stack.shift());
|
|
|
|
setTimeout(function() {
|
|
|
|
busy = false;
|
|
|
|
handleDebugMessage();
|
|
|
|
}, 15); // every 15mS = 66 times a second
|
|
|
|
if (stack.length > numMessages) { stack = stack.splice(-numMessages); }
|
|
|
|
}
|
|
|
|
}
|
2016-10-27 00:20:43 +02:00
|
|
|
|
2017-10-10 22:53:25 +02:00
|
|
|
function processDebugMessage(o) {
|
2019-05-09 11:06:10 +02:00
|
|
|
var msg = $("<div/>");
|
2016-10-27 09:48:32 +02:00
|
|
|
var sourceNode = o._source;
|
2016-10-27 00:20:43 +02:00
|
|
|
|
2019-05-09 11:06:10 +02:00
|
|
|
msg.on("mouseenter", function() {
|
2019-05-24 11:22:14 +02:00
|
|
|
msg.addClass('red-ui-debug-msg-hover');
|
2016-10-27 09:48:32 +02:00
|
|
|
if (o._source) {
|
2020-01-17 17:53:01 +01:00
|
|
|
// highlight the top-level node (could be subflow instance)
|
2016-10-27 09:48:32 +02:00
|
|
|
config.messageMouseEnter(o._source.id);
|
2018-04-17 13:44:58 +02:00
|
|
|
if (o._source._alias) {
|
2020-01-17 17:53:01 +01:00
|
|
|
// this is inside a subflow - highlight the node itself
|
2018-04-17 13:44:58 +02:00
|
|
|
config.messageMouseEnter(o._source._alias);
|
|
|
|
}
|
2020-01-17 17:53:01 +01:00
|
|
|
// if path.length > 2, we are nested - highlight subflow instances
|
|
|
|
for (var i=2;i<o._source.path.length;i++) {
|
|
|
|
config.messageMouseEnter(o._source.path[i]);
|
|
|
|
}
|
2016-10-27 00:20:43 +02:00
|
|
|
}
|
2019-05-09 11:06:10 +02:00
|
|
|
});
|
|
|
|
msg.on("mouseleave", function() {
|
2019-05-24 11:22:14 +02:00
|
|
|
msg.removeClass('red-ui-debug-msg-hover');
|
2016-10-27 09:48:32 +02:00
|
|
|
if (o._source) {
|
|
|
|
config.messageMouseLeave(o._source.id);
|
2018-04-17 13:44:58 +02:00
|
|
|
if (o._source._alias) {
|
|
|
|
config.messageMouseLeave(o._source._alias);
|
|
|
|
}
|
2020-01-17 17:53:01 +01:00
|
|
|
for (var i=2;i<o._source.path.length;i++) {
|
|
|
|
config.messageMouseLeave(o._source.path[i]);
|
|
|
|
}
|
2016-10-27 00:20:43 +02:00
|
|
|
}
|
2019-05-09 11:06:10 +02:00
|
|
|
});
|
2016-10-27 00:20:43 +02:00
|
|
|
var name = sanitize(((o.name?o.name:o.id)||"").toString());
|
|
|
|
var topic = sanitize((o.topic||"").toString());
|
|
|
|
var property = sanitize(o.property?o.property:'');
|
2016-11-27 22:51:34 +01:00
|
|
|
var payload = o.msg;
|
2016-10-27 00:20:43 +02:00
|
|
|
var format = sanitize((o.format||"").toString());
|
2019-05-24 11:22:14 +02:00
|
|
|
msg.attr("class", 'red-ui-debug-msg'+(o.level?(' red-ui-debug-msg-level-'+o.level):'')+
|
2017-05-22 12:35:45 +02:00
|
|
|
(sourceNode?(
|
2019-05-02 23:33:29 +02:00
|
|
|
" red-ui-debug-msg-node-"+sourceNode.id.replace(/\./g,"_")+
|
|
|
|
(sourceNode.z?" red-ui-debug-msg-flow-"+sourceNode.z.replace(/\./g,"_"):"")
|
2019-05-09 11:06:10 +02:00
|
|
|
):""));
|
2017-05-22 12:35:45 +02:00
|
|
|
|
|
|
|
if (sourceNode) {
|
2019-05-09 11:06:10 +02:00
|
|
|
msg.data('source',sourceNode.id);
|
2017-05-22 12:35:45 +02:00
|
|
|
if (filterType === "filterCurrent" && activeWorkspace) {
|
|
|
|
if (sourceNode.z && sourceNode.z.replace(/\./g,"_") !== activeWorkspace) {
|
2019-05-09 11:06:10 +02:00
|
|
|
msg.addClass('hide');
|
2017-05-22 12:35:45 +02:00
|
|
|
}
|
|
|
|
} else if (filterType === 'filterSelected'){
|
|
|
|
if (!!filteredNodes[sourceNode.id]) {
|
2019-05-09 11:06:10 +02:00
|
|
|
msg.addClass('hide');
|
2017-05-22 12:35:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-02 23:33:29 +02:00
|
|
|
var metaRow = $('<div class="red-ui-debug-msg-meta"></div>').appendTo(msg);
|
|
|
|
$('<span class="red-ui-debug-msg-date">'+ getTimestamp()+'</span>').appendTo(metaRow);
|
2016-10-27 00:20:43 +02:00
|
|
|
if (sourceNode) {
|
2020-03-29 21:38:05 +02:00
|
|
|
$('<a>',{href:"#",class:"red-ui-debug-msg-name"}).text('node: '+(o.name||sourceNode.name||sourceNode.id))
|
2016-11-16 16:05:04 +01:00
|
|
|
.appendTo(metaRow)
|
2019-04-29 12:50:15 +02:00
|
|
|
.on("click", function(evt) {
|
2016-10-27 00:20:43 +02:00
|
|
|
evt.preventDefault();
|
2020-01-17 17:53:01 +01:00
|
|
|
config.messageSourceClick(sourceNode.id, sourceNode._alias, sourceNode.path);
|
2016-10-27 00:20:43 +02:00
|
|
|
});
|
|
|
|
} else if (name) {
|
2019-05-02 23:33:29 +02:00
|
|
|
$('<span class="red-ui-debug-msg-name">'+name+'</span>').appendTo(metaRow);
|
2016-10-27 00:20:43 +02:00
|
|
|
}
|
2017-05-10 16:49:12 +02:00
|
|
|
|
2018-06-25 23:31:11 +02:00
|
|
|
payload = RED.utils.decodeObject(payload,format);
|
|
|
|
|
2019-05-02 23:33:29 +02:00
|
|
|
var el = $('<span class="red-ui-debug-msg-payload"></span>').appendTo(msg);
|
2017-05-12 11:19:50 +02:00
|
|
|
var path = o.property||'';
|
2017-08-01 00:29:36 +02:00
|
|
|
var debugMessage = RED.utils.createObjectElement(payload, {
|
|
|
|
key: /*true*/null,
|
|
|
|
typeHint: format,
|
|
|
|
hideKey: false,
|
|
|
|
path: path,
|
|
|
|
sourceId: sourceNode&&sourceNode.id,
|
|
|
|
rootPath: path
|
|
|
|
});
|
2017-05-12 23:12:55 +02:00
|
|
|
// Do this in a separate step so the element functions aren't stripped
|
|
|
|
debugMessage.appendTo(el);
|
|
|
|
// NOTE: relying on function error to have a "type" that all other msgs don't
|
|
|
|
if (o.hasOwnProperty("type") && (o.type === "function")) {
|
|
|
|
var errorLvlType = 'error';
|
|
|
|
var errorLvl = 20;
|
|
|
|
if (o.hasOwnProperty("level") && o.level === 30) {
|
|
|
|
errorLvl = 30;
|
|
|
|
errorLvlType = 'warn';
|
|
|
|
}
|
2019-05-24 11:22:14 +02:00
|
|
|
msg.addClass('red-ui-debug-msg-level-' + errorLvl);
|
2019-05-02 23:33:29 +02:00
|
|
|
$('<span class="red-ui-debug-msg-topic">function : (' + errorLvlType + ')</span>').appendTo(metaRow);
|
2017-05-12 23:12:55 +02:00
|
|
|
} else {
|
2019-05-02 23:33:29 +02:00
|
|
|
var tools = $('<span class="red-ui-debug-msg-tools button-group"></span>').appendTo(metaRow);
|
2019-05-17 11:42:43 +02:00
|
|
|
var filterMessage = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-caret-down"></i></button>').appendTo(tools);
|
2019-04-29 12:50:15 +02:00
|
|
|
filterMessage.on("click", function(e) {
|
2017-05-12 23:12:55 +02:00
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
showMessageMenu(filterMessage,debugMessage,sourceNode&&sourceNode.id);
|
|
|
|
});
|
2019-05-02 23:33:29 +02:00
|
|
|
$('<span class="red-ui-debug-msg-topic">'+
|
2017-05-12 23:12:55 +02:00
|
|
|
(o.topic?topic+' : ':'')+
|
|
|
|
(o.property?'msg.'+property:'msg')+" : "+format+
|
|
|
|
'</span>').appendTo(metaRow);
|
|
|
|
}
|
|
|
|
|
2016-10-27 00:20:43 +02:00
|
|
|
var atBottom = (sbc.scrollHeight-messageList.height()-sbc.scrollTop) < 5;
|
|
|
|
var m = {
|
|
|
|
el: msg
|
|
|
|
};
|
|
|
|
messages.push(m);
|
|
|
|
if (sourceNode) {
|
|
|
|
m.source = sourceNode;
|
|
|
|
messagesByNode[sourceNode.id] = m;
|
|
|
|
}
|
|
|
|
if (view == "list") {
|
|
|
|
messageList.append(msg);
|
|
|
|
} else {
|
|
|
|
if (sourceNode) {
|
2019-05-02 23:33:29 +02:00
|
|
|
var wrapper = $("#red-ui-debug-msg-source-"+sourceNode.id.replace(/\./g,"_"));
|
2016-10-27 00:20:43 +02:00
|
|
|
if (wrapper.length === 0 ) {
|
2019-05-02 23:33:29 +02:00
|
|
|
wrapper = $("<div>",{id:"red-ui-debug-msg-source-"+sourceNode.id.replace(/\./g,"_")}).appendTo(messageTable);
|
2016-10-27 00:20:43 +02:00
|
|
|
}
|
|
|
|
wrapper.empty();
|
|
|
|
wrapper.append(msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-10 22:53:25 +02:00
|
|
|
if (messages.length === numMessages) {
|
2016-11-02 01:16:36 +01:00
|
|
|
m = messages.shift();
|
2016-10-27 00:20:43 +02:00
|
|
|
if (view === "list") {
|
|
|
|
m.el.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (atBottom) {
|
|
|
|
messageList.scrollTop(sbc.scrollHeight);
|
|
|
|
}
|
|
|
|
}
|
2017-05-22 12:35:45 +02:00
|
|
|
|
2018-01-05 17:13:02 +01:00
|
|
|
function clearMessageList(clearFilter) {
|
2019-05-02 23:33:29 +02:00
|
|
|
$(".red-ui-debug-msg").remove();
|
2018-01-05 17:13:02 +01:00
|
|
|
config.clear();
|
|
|
|
if (!!clearFilter) {
|
|
|
|
clearFilterSettings();
|
|
|
|
}
|
|
|
|
refreshDebugNodeList();
|
|
|
|
}
|
|
|
|
|
|
|
|
function clearFilterSettings() {
|
|
|
|
filteredNodes = {};
|
|
|
|
filterType = 'filterAll';
|
2019-05-08 14:26:48 +02:00
|
|
|
$('.red-ui-sidebar-debug-filter-option').removeClass('selected');
|
|
|
|
$('#red-ui-sidebar-debug-filterAll').addClass('selected');
|
|
|
|
$('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll'));
|
2019-05-16 23:32:28 +02:00
|
|
|
$('#red-ui-sidebar-debug-filter-node-list-row').slideUp();
|
2018-01-05 17:13:02 +01:00
|
|
|
}
|
|
|
|
|
2016-10-24 17:53:09 +02:00
|
|
|
return {
|
2016-10-27 00:20:43 +02:00
|
|
|
init: init,
|
|
|
|
refreshMessageList:refreshMessageList,
|
2017-05-22 12:35:45 +02:00
|
|
|
handleDebugMessage: handleDebugMessage,
|
2018-01-16 12:21:54 +01:00
|
|
|
clearMessageList: clearMessageList
|
2016-10-24 17:53:09 +02:00
|
|
|
}
|
|
|
|
})();
|