Keep local/remote diff objects in sync as they expand

This commit is contained in:
Nick O'Leary 2017-07-31 23:29:36 +01:00
parent 5bdb9e972e
commit eaf08a9971
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
3 changed files with 175 additions and 24 deletions

View File

@ -563,6 +563,7 @@ RED.diff = (function() {
return div; return div;
} }
function createNodePropertiesTable(def,node,localNodeObj,remoteNodeObj) { function createNodePropertiesTable(def,node,localNodeObj,remoteNodeObj) {
var propertyElements = {};
var localNode = localNodeObj.node; var localNode = localNodeObj.node;
var remoteNode; var remoteNode;
if (remoteNodeObj) { if (remoteNodeObj) {
@ -589,7 +590,7 @@ RED.diff = (function() {
localCell.addClass("node-diff-node-unchanged"); localCell.addClass("node-diff-node-unchanged");
$('<span class="node-diff-status"></span>').appendTo(localCell); $('<span class="node-diff-status"></span>').appendTo(localCell);
element = $('<span class="node-diff-element"></span>').appendTo(localCell); element = $('<span class="node-diff-element"></span>').appendTo(localCell);
RED.utils.createObjectElement(localNode.id).appendTo(element); propertyElements['local.id'] = RED.utils.createObjectElement(localNode.id).appendTo(element);
} else { } else {
localCell.addClass("node-diff-empty"); localCell.addClass("node-diff-empty");
} }
@ -599,7 +600,7 @@ RED.diff = (function() {
if (remoteNode) { if (remoteNode) {
$('<span class="node-diff-status"></span>').appendTo(remoteCell); $('<span class="node-diff-status"></span>').appendTo(remoteCell);
element = $('<span class="node-diff-element"></span>').appendTo(remoteCell); element = $('<span class="node-diff-element"></span>').appendTo(remoteCell);
RED.utils.createObjectElement(remoteNode.id).appendTo(element); propertyElements['remote.id'] = RED.utils.createObjectElement(remoteNode.id).appendTo(element);
} else { } else {
remoteCell.addClass("node-diff-empty"); remoteCell.addClass("node-diff-empty");
} }
@ -632,7 +633,17 @@ RED.diff = (function() {
localCell.addClass("node-diff-node-"+(localChanged?"changed":"unchanged")); localCell.addClass("node-diff-node-"+(localChanged?"changed":"unchanged"));
$('<span class="node-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell); $('<span class="node-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell);
element = $('<span class="node-diff-element"></span>').appendTo(localCell); element = $('<span class="node-diff-element"></span>').appendTo(localCell);
RED.utils.createObjectElement({x:localNode.x,y:localNode.y}).appendTo(element); propertyElements['local.position'] = RED.utils.createObjectElement({x:localNode.x,y:localNode.y},
{
path: "position",
exposeApi: true,
ontoggle: function(path,state) {
if (propertyElements['remote.'+path]) {
propertyElements['remote.'+path].prop('expand')(path,state)
}
}
}
).appendTo(element);
} else { } else {
localCell.addClass("node-diff-empty"); localCell.addClass("node-diff-empty");
} }
@ -643,7 +654,17 @@ RED.diff = (function() {
if (remoteNode) { if (remoteNode) {
$('<span class="node-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell); $('<span class="node-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell);
element = $('<span class="node-diff-element"></span>').appendTo(remoteCell); element = $('<span class="node-diff-element"></span>').appendTo(remoteCell);
RED.utils.createObjectElement({x:remoteNode.x,y:remoteNode.y}).appendTo(element); propertyElements['remote.position'] = RED.utils.createObjectElement({x:remoteNode.x,y:remoteNode.y},
{
path: "position",
exposeApi: true,
ontoggle: function(path,state) {
if (propertyElements['local.'+path]) {
propertyElements['local.'+path].prop('expand')(path,state);
}
}
}
).appendTo(element);
} else { } else {
remoteCell.addClass("node-diff-empty"); remoteCell.addClass("node-diff-empty");
} }
@ -748,7 +769,17 @@ RED.diff = (function() {
$('<span class="node-diff-status"><i class="fa fa-exclamation"></i></span>').appendTo(localCell); $('<span class="node-diff-status"><i class="fa fa-exclamation"></i></span>').appendTo(localCell);
} }
element = $('<span class="node-diff-element"></span>').appendTo(localCell); element = $('<span class="node-diff-element"></span>').appendTo(localCell);
RED.utils.createObjectElement(localNode[d]).appendTo(element); propertyElements['local.'+d] = RED.utils.createObjectElement(localNode[d],
{
path: d,
exposeApi: true,
ontoggle: function(path,state) {
if (propertyElements['remote.'+d]) {
propertyElements['remote.'+d].prop('expand')(path,state)
}
}
}
).appendTo(element);
} else { } else {
localCell.addClass("node-diff-empty"); localCell.addClass("node-diff-empty");
} }
@ -763,7 +794,17 @@ RED.diff = (function() {
$('<span class="node-diff-status"><i class="fa fa-exclamation"></i></span>').appendTo(remoteCell); $('<span class="node-diff-status"><i class="fa fa-exclamation"></i></span>').appendTo(remoteCell);
} }
element = $('<span class="node-diff-element"></span>').appendTo(remoteCell); element = $('<span class="node-diff-element"></span>').appendTo(remoteCell);
RED.utils.createObjectElement(remoteNode[d]).appendTo(element); propertyElements['remote.'+d] = RED.utils.createObjectElement(remoteNode[d],
{
path: d,
exposeApi: true,
ontoggle: function(path,state) {
if (propertyElements['local.'+d]) {
propertyElements['local.'+d].prop('expand')(path,state)
}
}
}
).appendTo(element);
} else { } else {
remoteCell.addClass("node-diff-empty"); remoteCell.addClass("node-diff-empty");
} }
@ -1009,6 +1050,7 @@ RED.diff = (function() {
// console.log(conflicted); // console.log(conflicted);
return diff; return diff;
} }
function showDiff(diff) { function showDiff(diff) {
var localDiff = diff.localDiff; var localDiff = diff.localDiff;
var remoteDiff = diff.remoteDiff; var remoteDiff = diff.remoteDiff;
@ -1267,7 +1309,6 @@ RED.diff = (function() {
RED.palette.refresh(); RED.palette.refresh();
RED.workspaces.refresh(); RED.workspaces.refresh();
RED.sidebar.config.refresh(); RED.sidebar.config.refresh();
} }
return { return {
init: init, init: init,

View File

@ -50,24 +50,58 @@ RED.utils = (function() {
} }
return result; return result;
} }
function makeExpandable(el,onexpand,expand) { function makeExpandable(el,onbuild,ontoggle,expand) {
el.addClass("debug-message-expandable"); el.addClass("debug-message-expandable");
el.prop('toggle',function() {
return function(state) {
var parent = el.parent();
if (parent.hasClass('collapsed')) {
if (state) {
if (onbuild && !parent.hasClass('built')) {
onbuild();
parent.addClass('built');
}
parent.removeClass('collapsed');
return true;
}
} else {
if (!state) {
parent.addClass('collapsed');
return true;
}
}
return false;
}
});
el.click(function(e) { el.click(function(e) {
var parent = $(this).parent(); var parent = $(this).parent();
if (parent.hasClass('collapsed')) { var currentState = !parent.hasClass('collapsed');
if (onexpand && !parent.hasClass('built')) { if ($(this).prop('toggle')(!currentState)) {
onexpand(); if (ontoggle) {
parent.addClass('built'); ontoggle(!currentState);
} }
parent.removeClass('collapsed');
} else {
parent.addClass('collapsed');
} }
// if (parent.hasClass('collapsed')) {
// if (onbuild && !parent.hasClass('built')) {
// onbuild();
// parent.addClass('built');
// }
// if (ontoggle) {
// ontoggle(true);
// }
// parent.removeClass('collapsed');
// } else {
// parent.addClass('collapsed');
// if (ontoggle) {
// ontoggle(false);
// }
// }
e.preventDefault(); e.preventDefault();
}); });
if (expand) { if (expand) {
el.click(); el.click();
} }
} }
var pinnedPaths = {}; var pinnedPaths = {};
@ -189,10 +223,23 @@ RED.utils = (function() {
} }
} }
function buildMessageElement(obj,key,typeHint,hideKey,path,sourceId,rootPath,expandPaths) { function buildMessageElement(obj,options) {
options = options || {};
var key = options.key;
var typeHint = options.typeHint;
var hideKey = options.hideKey;
var path = options.path;
var sourceId = options.sourceId;
var rootPath = options.rootPath;
var expandPaths = options.expandPaths;
var ontoggle = options.ontoggle;
var exposeApi = options.exposeApi;
var subElements = {};
var i; var i;
var e; var e;
var entryObj; var entryObj;
var expandableHeader;
var header; var header;
var headerHead; var headerHead;
var value; var value;
@ -257,7 +304,7 @@ RED.utils = (function() {
$('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html(typeHint||'string').appendTo(header); $('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html(typeHint||'string').appendTo(header);
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element); var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element);
$('<pre class="debug-message-type-string"></pre>').text(obj).appendTo(row); $('<pre class="debug-message-type-string"></pre>').text(obj).appendTo(row);
},checkExpanded(strippedKey,expandPaths)); },function(state) {if (ontoggle) { ontoggle(path,state);}}, checkExpanded(strippedKey,expandPaths));
} }
e = $('<span class="debug-message-type-string debug-message-object-header"></span>').html('"'+formatString(sanitize(obj))+'"').appendTo(entryObj); e = $('<span class="debug-message-type-string debug-message-object-header"></span>').html('"'+formatString(sanitize(obj))+'"').appendTo(entryObj);
if (/^#[0-9a-f]{6}$/i.test(obj)) { if (/^#[0-9a-f]{6}$/i.test(obj)) {
@ -356,7 +403,20 @@ RED.utils = (function() {
if (fullLength <= 10) { if (fullLength <= 10) {
for (i=0;i<fullLength;i++) { for (i=0;i<fullLength;i++) {
row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(arrayRows); row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(arrayRows);
buildMessageElement(data[i],""+i,type==='buffer'?'hex':false,false,path+"["+i+"]",sourceId,rootPath,expandPaths).appendTo(row); subElements[path+"["+i+"]"] = buildMessageElement(
data[i],
{
key: ""+i,
typeHint: type==='buffer'?'hex':false,
hideKey: false,
path: path+"["+i+"]",
sourceId: sourceId,
rootPath: rootPath,
expandPaths: expandPaths,
ontoggle: ontoggle,
exposeApi: exposeApi
}
).appendTo(row);
} }
} else { } else {
for (i=0;i<fullLength;i+=10) { for (i=0;i<fullLength;i+=10) {
@ -371,17 +431,35 @@ RED.utils = (function() {
return function() { return function() {
for (var i=min;i<=max;i++) { for (var i=min;i<=max;i++) {
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(parent); var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(parent);
buildMessageElement(data[i],""+i,type==='buffer'?'hex':false,false,path+"["+i+"]",sourceId,rootPath,expandPaths).appendTo(row); subElements[path+"["+i+"]"] = buildMessageElement(
data[i],
{
key: ""+i,
typeHint: type==='buffer'?'hex':false,
hideKey: false,
path: path+"["+i+"]",
sourceId: sourceId,
rootPath: rootPath,
expandPaths: expandPaths,
ontoggle: ontoggle,
exposeApi: exposeApi
}
).appendTo(row);
} }
} }
})(),checkExpanded(strippedKey,expandPaths,minRange,Math.min(fullLength-1,(minRange+9)))); })(),
(function() { var path = path+"["+i+"]"; return function(state) {if (ontoggle) { ontoggle(path,state);}}})(),
checkExpanded(strippedKey,expandPaths,minRange,Math.min(fullLength-1,(minRange+9))));
$('<span class="debug-message-object-key"></span>').html("["+minRange+" &hellip; "+Math.min(fullLength-1,(minRange+9))+"]").appendTo(header); $('<span class="debug-message-object-key"></span>').html("["+minRange+" &hellip; "+Math.min(fullLength-1,(minRange+9))+"]").appendTo(header);
} }
if (fullLength < originalLength) { if (fullLength < originalLength) {
$('<div class="debug-message-object-entry collapsed"><span class="debug-message-object-key">['+fullLength+' &hellip; '+originalLength+']</span></div>').appendTo(arrayRows); $('<div class="debug-message-object-entry collapsed"><span class="debug-message-object-key">['+fullLength+' &hellip; '+originalLength+']</span></div>').appendTo(arrayRows);
} }
} }
},checkExpanded(strippedKey,expandPaths)); },
function(state) {if (ontoggle) { ontoggle(path,state);}},
checkExpanded(strippedKey,expandPaths));
} }
} else if (typeof obj === 'object') { } else if (typeof obj === 'object') {
element.addClass('collapsed'); element.addClass('collapsed');
@ -402,12 +480,28 @@ RED.utils = (function() {
newPath += "[\""+keys[i].replace(/"/,"\\\"")+"\"]" newPath += "[\""+keys[i].replace(/"/,"\\\"")+"\"]"
} }
} }
buildMessageElement(obj[keys[i]],keys[i],false,false,newPath,sourceId,rootPath,expandPaths).appendTo(row); subElements[newPath] = buildMessageElement(
obj[keys[i]],
{
key: keys[i],
typeHint: false,
hideKey: false,
path: newPath,
sourceId: sourceId,
rootPath: rootPath,
expandPaths: expandPaths,
ontoggle: ontoggle,
exposeApi: exposeApi
}
).appendTo(row);
} }
if (keys.length === 0) { if (keys.length === 0) {
$('<div class="debug-message-object-entry debug-message-type-meta collapsed"></div>').text("empty").appendTo(element); $('<div class="debug-message-object-entry debug-message-type-meta collapsed"></div>').text("empty").appendTo(element);
} }
},checkExpanded(strippedKey,expandPaths)); },
function(state) {if (ontoggle) { ontoggle(path,state);}},
checkExpanded(strippedKey,expandPaths));
} }
if (key) { if (key) {
$('<span class="debug-message-type-meta"></span>').html('object').appendTo(entryObj); $('<span class="debug-message-type-meta"></span>').html('object').appendTo(entryObj);
@ -434,6 +528,15 @@ RED.utils = (function() {
} else { } else {
$('<span class="debug-message-type-other"></span>').text(""+obj).appendTo(entryObj); $('<span class="debug-message-type-other"></span>').text(""+obj).appendTo(entryObj);
} }
if (exposeApi) {
element.prop('expand', function() { return function(targetPath, state) {
if (path === targetPath) {
header.prop('toggle')(state);
} else if (subElements[targetPath]) {
subElements[targetPath].prop('expand')(targetPath,state);
}
}});
}
return element; return element;
} }

View File

@ -441,7 +441,14 @@ RED.debug = (function() {
} }
var el = $('<span class="debug-message-payload"></span>').appendTo(msg); var el = $('<span class="debug-message-payload"></span>').appendTo(msg);
var path = o.property||''; var path = o.property||'';
var debugMessage = RED.utils.createObjectElement(payload,/*true*/null,format,false,path,sourceNode&&sourceNode.id,path); var debugMessage = RED.utils.createObjectElement(payload, {
key: /*true*/null,
typeHint: format,
hideKey: false,
path: path,
sourceId: sourceNode&&sourceNode.id,
rootPath: path
});
// Do this in a separate step so the element functions aren't stripped // Do this in a separate step so the element functions aren't stripped
debugMessage.appendTo(el); debugMessage.appendTo(el);
// NOTE: relying on function error to have a "type" that all other msgs don't // NOTE: relying on function error to have a "type" that all other msgs don't