From 51bad3bf3cce6c2e3c4631c7c9eab3afa75861a7 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Sun, 20 Aug 2017 22:59:51 +0100 Subject: [PATCH] Add dual text-diff --- editor/js/ui/diff.js | 316 ++++++++++++++++++++++++++++++++++++++++++ editor/js/ui/tray.js | 17 ++- editor/sass/diff.scss | 68 +++++++++ 3 files changed, 396 insertions(+), 5 deletions(-) diff --git a/editor/js/ui/diff.js b/editor/js/ui/diff.js index 26c73c9a0..68618de74 100644 --- a/editor/js/ui/diff.js +++ b/editor/js/ui/diff.js @@ -11,6 +11,15 @@ RED.diff = (function() { // RED.keyboard.add("*","ctrl-shift-l","core:show-current-diff"); RED.keyboard.add("*","ctrl-shift-r","core:show-remote-diff"); + + RED.actions.add("core:show-test-flow-diff-1",function(){showTestFlowDiff(1)}); + RED.keyboard.add("*","ctrl-shift-f 1","core:show-test-flow-diff-1"); + + RED.actions.add("core:show-test-flow-diff-2",function(){showTestFlowDiff(2)}); + RED.keyboard.add("*","ctrl-shift-f 2","core:show-test-flow-diff-2"); + RED.actions.add("core:show-test-flow-diff-3",function(){showTestFlowDiff(3)}); + RED.keyboard.add("*","ctrl-shift-f 3","core:show-test-flow-diff-3"); + } function buildDiffPanel(container) { @@ -794,6 +803,15 @@ RED.diff = (function() { remoteCell.addClass("node-diff-empty"); } } + if (localNode && remoteNode && typeof localNode[d] === "string") { + if (/\n/.test(localNode[d]) || /\n/.test(remoteNode[d])) { + $('').click(function() { + showTextDiff(localNode[d],remoteNode[d]); + }).appendTo(propertyNameCell); + } + } + + }); return nodePropertiesDiv; } @@ -1333,6 +1351,304 @@ RED.diff = (function() { RED.workspaces.refresh(); RED.sidebar.config.refresh(); } + function showTestFlowDiff(index) { + if (index === 1) { + var localFlow = RED.nodes.createCompleteNodeSet(); + var originalFlow = RED.nodes.originalFlow(); + showTextDiff(JSON.stringify(localFlow,null,4),JSON.stringify(originalFlow,null,4)) + } else if (index === 2) { + var local = "1\n2\n3\n4\n5\nA\n6\n7\n8\n9\n"; + var remote = "1\nA\n2\n3\nD\nE\n6\n7\n8\n9\n"; + showTextDiff(local,remote); + } else if (index === 3) { + var local = "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22"; + var remote = "1\nTWO\nTHREE\nEXTRA\n4\n5\n6\n7\n8\n9\n10\n11\n12\nTHIRTEEN\n14\n15\n16\n17\n18\n19\n20\n21\n22"; + showTextDiff(local,remote); + } + } + + function showTextDiff(textA,textB) { + var trayOptions = { + title: "Compare Changes", //TODO: nls + width: Infinity, + overlay: true, + buttons: [ + { + text: RED._("common.label.done"), + click: function() { + RED.tray.close(); + } + } + ], + resize: function(dimensions) { + // trayWidth = dimensions.width; + }, + open: function(tray) { + var trayBody = tray.find('.editor-tray-body'); + var diffPanel = $('
').appendTo(trayBody); + + var codeTable = $("").appendTo(diffPanel); + $('').appendTo(codeTable); + var codeBody = $('').appendTo(codeTable); + var diffSummary = diffText(textA||"",textB||""); + var aIndex = 0; + var bIndex = 0; + var diffLength = Math.max(diffSummary.a.length, diffSummary.b.length); + + var diffLines = []; + var diffBlocks = []; + var currentBlock; + var blockLength = 0; + var blockType = 0; + + for (var i=0;i 3) { + currentBlock.end -= 3; + currentBlock.empty = true; + diffBlocks.push(currentBlock); + currentBlock = {start:i-3,end:i-3}; + } + blockType = 1; + } else if (blockType === 2) { + // we were in unchanged, but hit a change again + blockType = 1; + } + } + } + } + if (blockType === 0) { + currentBlock.empty = true; + } + currentBlock.end = diffLength; + diffBlocks.push(currentBlock); +console.table(diffBlocks); + var diffRow; + for (var b = 0; b'); + var content = $('').appendTo(diffRow); + var label = $('').appendTo(content); + if (end < diffLines.length-1) { + label.text("@@ -"+(diffLines[end-1].a.i+1)+" +"+(diffLines[end-1].b.i+1)); + } + diffRow.click(function(evt) { + console.log(start,end,diffLines.length); + if (end - start > 20) { + var startPos = $(this).offset(); + console.log(startPos); + if (start > 0) { + for (var i=start;iend-11;i--) { + createDiffLine(diffLines[i]).addClass("unchanged").insertAfter($(this)); + } + end -= 10; + } + if (end < diffLines.length-1) { + label.text("@@ -"+(diffLines[end-1].a.i+1)+" +"+(diffLines[end-1].b.i+1)); + } + var endPos = $(this).offset(); + var delta = endPos.top - startPos.top; + $(".node-text-diff").scrollTop($(".node-text-diff").scrollTop() + delta); + } else { + for (var i=start;i'); + var Adiff = diffLine.a; + var Bdiff = diffLine.b; + //console.log(diffLine); + var cellNo = $("
").text(Adiff.type === 2?"":Adiff.i).appendTo(diffRow); + var cellLine = $("").text(Adiff.line).appendTo(diffRow); + if (Adiff.type === 2) { + cellNo.addClass('blank'); + cellLine.addClass('blank'); + } else if (Adiff.type === 1) { + cellNo.addClass('added'); + cellLine.addClass('added'); + } else if (Adiff.type === 4) { + cellNo.addClass('removed'); + cellLine.addClass('removed'); + } + cellNo = $("").text(Bdiff.type === 2?"":Bdiff.i).appendTo(diffRow); + cellLine = $("").text(Bdiff.line).appendTo(diffRow); + if (Bdiff.type === 2) { + cellNo.addClass('blank'); + cellLine.addClass('blank'); + } else if (Bdiff.type === 1) { + cellNo.addClass('added'); + cellLine.addClass('added'); + } else if (Bdiff.type === 4) { + cellNo.addClass('removed'); + cellLine.addClass('removed'); + } + return diffRow; + } + + function diffText(string1, string2,ignoreWhitespace) { + var lines1 = string1.split(/\r?\n/); + var lines2 = string2.split(/\r?\n/); + var i = lines1.length; + var j = lines2.length; + var k; + var m; + var diffSummary = {a:[],b:[]}; + var diffMap = []; + for (k = 0; k < i + 1; k++) { + diffMap[k] = []; + for (m = 0; m < j + 1; m++) { + diffMap[k][m] = 0; + } + } + var c = 0; + for (k = i - 1; k >= 0; k--) { + for (m = j - 1; m >=0; m--) { + c++; + if (compareLines(lines1[k],lines2[m],ignoreWhitespace) !== 1) { + diffMap[k][m] = diffMap[k+1][m+1]+1; + } else { + diffMap[k][m] = Math.max(diffMap[(k + 1)][m], diffMap[k][(m + 1)]); + } + } + } + //console.log(c); + k = 0; + m = 0; + + while ((k < i) && (m < j)) { + var n = compareLines(lines1[k],lines2[m],ignoreWhitespace); + if (n !== 1) { + var d = 0; + if (n===0) { + d = 0; + } else if (n==2) { + d = 3; + } + diffSummary.a.push({i:k+1,j:m+1,line:lines1[k],type:d}); + diffSummary.b.push({i:m+1,j:k+1,line:lines2[m],type:d}); + k++; + m++; + } else if (diffMap[(k + 1)][m] >= diffMap[k][(m + 1)]) { + diffSummary.a.push({i:k+1,line:lines1[k],type:1}); + k++; + } else { + diffSummary.b.push({i:m+1,line:lines2[m],type:4}); + m++; + } + } + while ((k < i) || (m < j)) { + if (k == i) { + diffSummary.b.push({i:m+1,line:lines2[m],type:4}); + m++; + } else if (m == j) { + diffSummary.a.push({i:k+1,line:lines1[k],type:1}); + k++; + } + } + return diffSummary; + } + + function compareLines(string1, string2, ignoreWhitespace) { + if (ignoreWhitespace) { + if (string1 === string2) { + return 0; + } + return string1.trim() === string2.trime() ? 2 : 1; + } + return string1 === string2 ? 0 : 1; + } + + + + return { init: init, getRemoteDiff: getRemoteDiff, diff --git a/editor/js/ui/tray.js b/editor/js/ui/tray.js index c8a09232b..416265152 100644 --- a/editor/js/ui/tray.js +++ b/editor/js/ui/tray.js @@ -210,7 +210,7 @@ RED.tray = (function() { }); }, show: function show(options) { - if (stack.length > 0) { + if (stack.length > 0 && !options.overlay) { var oldTray = stack[stack.length-1]; oldTray.tray.css({ right: -(oldTray.tray.width()+10)+"px" @@ -238,14 +238,21 @@ RED.tray = (function() { tray.tray.remove(); if (stack.length > 0) { var oldTray = stack[stack.length-1]; - oldTray.tray.appendTo("#editor-stack"); - setTimeout(function() { + if (!oldTray.options.overlay) { + oldTray.tray.appendTo("#editor-stack"); + setTimeout(function() { + handleWindowResize(); + oldTray.tray.css({right:0}); + if (oldTray.options.show) { + oldTray.options.show(); + } + },0); + } else { handleWindowResize(); - oldTray.tray.css({right:0}); if (oldTray.options.show) { oldTray.options.show(); } - },0); + } } if (done) { done(); diff --git a/editor/sass/diff.scss b/editor/sass/diff.scss index 679d24520..78f5e9174 100644 --- a/editor/sass/diff.scss +++ b/editor/sass/diff.scss @@ -49,6 +49,10 @@ height: 25px; display: inline-block; box-sizing: border-box; + padding-top: 2px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; width: 50%; background: #f9f9f9; text-align: center; @@ -535,3 +539,67 @@ #node-diff-toolbar-resolved-conflicts .node-diff-status { margin:0; } +.node-diff-text-diff-button { + float: right; + margin: 2px 3px; + line-height: 14px; + height: 16px; + +} +.node-text-diff { + height: 100%; + overflow-y:auto; + table { + margin: 10px; + border: 1px solid $secondary-border-color; + border-radius: 3px; + font-family: monospace; + table-layout: fixed; + width: calc(100% - 20px); + } + td { + vertical-align: top; + word-wrap: break-word; + } + td:nth-child(odd) { + text-align: right; + color: #999; + background: #fafafa; + padding: 1px 5px; + } + td:nth-child(3) { + border-left: 1px solid $secondary-border-color; + } + td:nth-child(even) { + white-space: pre-wrap; + padding: 1px 5px; + } + td.blank { + background: #f6f6f6; + } + td.added { + background: #eefaee; + } + td.removed { + background: #fadddd; + } + tr.unchanged { + background: #fefefe; + } + tr.start-block { + border-top: 1px solid #f3f3f3; + } + tr.end-block { + border-bottom: 1px solid #f3f3f3; + } + tr.node-text-diff-expand td { + text-align: left; + color: #999; + background: #ffd; + &:hover { + cursor: pointer; + background: #ffc; + } + } + +}