diff --git a/nodes/core/core/58-debug.html b/nodes/core/core/58-debug.html index af6bfdaf0..37ec8a208 100644 --- a/nodes/core/core/58-debug.html +++ b/nodes/core/core/58-debug.html @@ -44,6 +44,8 @@

Optionally can show the complete msg object, and send messages to the console log.

In addition any calls to node.warn or node.error will appear here.

+ + - diff --git a/nodes/core/core/lib/debug/debug-utils.js b/nodes/core/core/lib/debug/debug-utils.js index 7084c88ae..2aab49e90 100644 --- a/nodes/core/core/lib/debug/debug-utils.js +++ b/nodes/core/core/lib/debug/debug-utils.js @@ -1,5 +1,168 @@ RED.debug = (function() { + var config; + var messageList; + var messageTable; + var filter = false; + var view = 'list'; + var messages = []; + var messagesByNode = {}; + var sbc; + var activeWorkspace; + + /** + * messageMouseOver + * messageMouseOut + * messageSourceClick + * clear + * + */ + function init(_config) { + config = _config; + + var content = $("
").css({"position":"relative","height":"100%"}); + var toolbar = $('').appendTo(content); + + + var footerToolbar = $('
'+ + // ''+ + // 'list'+ + // 'table '+ + // ''+ + ' ' + + '
'); + + messageList = $('
').appendTo(content); + sbc = messageList[0]; + messageTable = $('
').appendTo(content); + + var filterDialog = $('
'+ + '
'+ + ''+ + ''+ + ' '+ + ''+ + '
'+ + '
').appendTo(content); + + content.i18n(); + + + filterDialog.find('#debug-tab-filter-all').on("click",function(e) { + e.preventDefault(); + if (filter) { + $(this).addClass('selected'); + $('#debug-tab-filter-current').removeClass('selected'); + filter = !filter; + refreshMessageList(); + } + }); + filterDialog.find('#debug-tab-filter-current').on("click",function(e) { + e.preventDefault(); + if (!filter) { + $(this).addClass('selected'); + $('#debug-tab-filter-all').removeClass('selected'); + filter = !filter; + refreshMessageList(); + } + }); + // $('#debug-tab-view-list').on("click",function(e) { + // e.preventDefault(); + // if (!$(this).hasClass('selected')) { + // $(this).addClass('selected'); + // $('#debug-tab-view-table').removeClass('selected'); + // showMessageList(); + // } + // }); + // $('#debug-tab-view-table').on("click",function(e) { + // e.preventDefault(); + // if (!$(this).hasClass('selected')) { + // $(this).addClass('selected'); + // $('#debug-tab-view-list').removeClass('selected'); + // showMessageTable(); + // } + // }); + + + toolbar.find('#debug-tab-filter').on("click",function(e) { + e.preventDefault(); + if ($(this).hasClass('selected')) { + $(this).removeClass('selected'); + filterDialog.slideUp(200); + } else { + $(this).addClass('selected'); + filterDialog.slideDown(200); + } + }) + + toolbar.find("#debug-tab-clear").click(function(e) { + e.preventDefault(); + $(".debug-message").remove(); + messageCount = 0; + config.clear(); + }); + + + return { + content: content, + footer: footerToolbar + } + + } + + function getTimestamp() { + var d = new Date(); + return d.toLocaleString(); + } + + function sanitize(m) { + return m.replace(/&/g,"&").replace(//g,">"); + } + + function refreshMessageList(_activeWorkspace) { + if (_activeWorkspace) { + activeWorkspace = _activeWorkspace; + } + $(".debug-message").each(function() { + console.log() + $(this).toggleClass('hide',filter&&!$(this).hasClass('debug-message-flow-'+activeWorkspace)); + }); + } + 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) { + var wrapper = $("
",{id:"debug-message-source-"+sourceNode.id.replace(/\./g,"_")}).appendTo(messageTable); + wrapper.append(msg); + } + }); + messageTable.show(); + } + + + function buildMessageElement(obj,topLevel,typeHint) { var i; var e; @@ -170,7 +333,109 @@ RED.debug = (function() { } return element; } + + function handleDebugMessage(o) { + var msg = document.createElement("div"); + + var sourceNode = o.sourceNode; + + msg.onmouseover = function() { + msg.style.borderRightColor = "#999"; + if (o.sourceNode) { + config.messageMouseOver(o.sourceNode.id); + } + }; + msg.onmouseout = function() { + msg.style.borderRightColor = ""; + if (o.sourceNode) { + config.messageMouseOut(o.sourceNode.id); + } + }; + var name = sanitize(((o.name?o.name:o.id)||"").toString()); + var topic = sanitize((o.topic||"").toString()); + var property = sanitize(o.property?o.property:''); + var payload = sanitize((o.msg||"").toString()); + var format = sanitize((o.format||"").toString()); + msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'') + + ((sourceNode&&sourceNode.z)?((" debug-message-flow-"+sourceNode.z+((filter&&(activeWorkspace!==sourceNode.z))?" hide":""))):""); + $(''+ getTimestamp()+'').appendTo(msg); + if (sourceNode) { + $('',{href:"#",class:"debug-message-name"}).html('node: '+sourceNode.id) + .appendTo(msg) + .click(function(evt) { + evt.preventDefault(); + config.messageSourceClick(sourceNode.id); + }); + } else if (name) { + $(''+name+'').appendTo(msg); + } + // 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'; + } + $(msg).addClass('debug-message-level-' + errorLvl); + $('function : (' + errorLvlType + ')').appendTo(msg); + } else { + $(''+ + (o.topic?topic+' : ':'')+ + (o.property?'msg.'+property:'msg')+" : "+format+ + '').appendTo(msg); + } + if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) { + payload = JSON.parse(payload); + } else if (format === 'null') { + payload = null; + } else if (format === 'undefined') { + payload = undefined; + } else if (/^buffer/.test(format)) { + var buffer = payload; + payload = []; + for (var c = 0; c < buffer.length; c += 2) { + payload.push(parseInt(buffer.substr(c, 2), 16)); + } + } + var el = $('').appendTo(msg); + buildMessageElement(payload,true,format).appendTo(el); + 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) { + var wrapper = $("#debug-message-source-"+sourceNode.id.replace(/\./g,"_")); + if (wrapper.length === 0 ) { + wrapper = $("
",{id:"debug-message-source-"+sourceNode.id.replace(/\./g,"_")}).appendTo(messageTable); + } + wrapper.empty(); + wrapper.append(msg); + } + } + + if (messages.length === 100) { + var m = messages.shift(); + if (view === "list") { + m.el.remove(); + } + } + if (atBottom) { + messageList.scrollTop(sbc.scrollHeight); + } + } return { - buildMessageElement: buildMessageElement + init: init, + buildMessageElement: buildMessageElement, + refreshMessageList:refreshMessageList, + handleDebugMessage: handleDebugMessage } })();