From 91f47a4e20d8178dac7b2af9ab240c5424dc5731 Mon Sep 17 00:00:00 2001 From: Matt Pass Date: Wed, 29 Oct 2014 12:43:03 +0000 Subject: [PATCH] Inner line diff highlighting on replaced lines Loops through all changed lines and marks 3 ranges for pre, on and post change on those lines Applies to both main and diff panes --- lib/ice-coder.js | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/ice-coder.js b/lib/ice-coder.js index dedc3dd..c324deb 100644 --- a/lib/ice-coder.js +++ b/lib/ice-coder.js @@ -359,7 +359,7 @@ var ICEcoder = { // Update diffs shown to the user in each pane updateDiffs: function() { - var cM, cMdiff, mainText, diffText, sm, opcodes, cMmarks, cMdiffMarks, amt, markColor; + var cM, cMdiff, mainText, diffText, sm, opcodes, cMmarks, cMdiffMarks, amt, sDiffs; // Reset the style array container and main vs diff pane shift difference top.ICEcoder.renderLineStyle = []; @@ -407,11 +407,17 @@ var ICEcoder = { if (amt > cM.defaultTextHeight()) { top.ICEcoder.renderLineStyle.push(["main", opcodes[i][2], "height", amt + "px"]); } + // Mark text in 2 colours, for each line + for (var j=0; j<(opcodes[i][2]) - (opcodes[i][1]); j++) { + sDiffs = (top.ICEcoder.findStringDiffs(cM.getLine(opcodes[i][1]+j),cMdiff.getLine(opcodes[i][3]+j))); + cM.markText({line: opcodes[i][1]+j, ch: 0}, {line: opcodes[i][3]+j + top.ICEcoder.renderPaneShiftAmount, ch: sDiffs[0]}, {className: "diffGreyLighter"}); + cM.markText({line: opcodes[i][1]+j, ch: sDiffs[0]}, {line: opcodes[i][3]+j + top.ICEcoder.renderPaneShiftAmount, ch: sDiffs[0]+sDiffs[1]}, {className: "diffGrey"}); + cM.markText({line: opcodes[i][1]+j, ch: sDiffs[0]+sDiffs[1]}, {line: opcodes[i][3]+j + top.ICEcoder.renderPaneShiftAmount, ch: 1000000}, {className: "diffGreyLighter"}); + } + // Inserting + } else { + cM.markText({line: opcodes[i][1], ch: 0}, {line: opcodes[i][2]-1, ch: 1000000}, {className: "diffGreen"}); } - // Replacing is grey, green in this pane if inserting - markColor = opcodes[i][0] == "replace" ? "diffGrey" : "diffGreen"; - // Mark the range with that class - cM.markText({line: opcodes[i][1], ch: 0}, {line: opcodes[i][2]-1, ch: 1000000}, {className: markColor}); // If inserting or deleting and the main pane hasn't changed, we need to pad out the line in that pane if (opcodes[i][0] != "replace" && opcodes[i][1] == opcodes[i][2]) { @@ -432,13 +438,18 @@ var ICEcoder = { if (amt > cM.defaultTextHeight()) { top.ICEcoder.renderLineStyle.push(["diff", opcodes[i][4], "height", amt + "px"]); } + // Mark text in 2 colours, for each line + for (var j=0; j<(opcodes[i][4]) - (opcodes[i][3]); j++) { + sDiffs = (top.ICEcoder.findStringDiffs(cM.getLine(opcodes[i][1]+j),cMdiff.getLine(opcodes[i][3]+j))); + cMdiff.markText({line: opcodes[i][1]+j - top.ICEcoder.renderPaneShiftAmount, ch: 0}, {line: opcodes[i][3]+j, ch: sDiffs[0]}, {className: "diffGreyLighter"}); + cMdiff.markText({line: opcodes[i][1]+j - top.ICEcoder.renderPaneShiftAmount, ch: sDiffs[0]}, {line: opcodes[i][3]+j, ch: sDiffs[0]+sDiffs[2]}, {className: "diffGrey"}); + cMdiff.markText({line: opcodes[i][1]+j - top.ICEcoder.renderPaneShiftAmount, ch: sDiffs[0]+sDiffs[2]}, {line: opcodes[i][3]+j, ch: 1000000}, {className: "diffGreyLighter"}); + } + // Deleting + } else { + cMdiff.markText({line: opcodes[i][3], ch: 0}, {line: opcodes[i][4]-1, ch: 1000000}, {className: "diffRed"}); } - // Replacing is grey, red in this pane if deleting - markColor = opcodes[i][0] == "replace" ? "diffGrey" : "diffRed"; - // Mark the range with that class - cMdiff.markText({line: opcodes[i][3], ch: 0}, {line: opcodes[i][4]-1, ch: 1000000}, {className: markColor}); - // If inserting or deleting and the diff pane hasn't changed, we need to pad out the line in that pane if (opcodes[i][0] != "replace" && opcodes[i][3] == opcodes[i][4]) { top.ICEcoder.renderLineStyle.push(["diff", opcodes[i][4], "height", ((opcodes[i][2] - opcodes[i][1] + 1) * cM.defaultTextHeight()) + "px"]); @@ -452,6 +463,22 @@ var ICEcoder = { } }, + // Find diffs between 2 strings + findStringDiffs: function(a, b) { + if ("undefined" == typeof a) {a = ""}; + if ("undefined" == typeof b) {b = ""}; + for (var c = 0, // start from the first character + d = a.length, e = b.length; // and from the last characters of both strings + a[c] && // if not at the end of the string and + a[c] == b[c]; // if both strings are equal at this position + c++); // go forward + for (; d > c & e > c & // stop at the position found by the first loop + a[d - 1] == b[e - 1]; // if both strings are equal at this position + d--) e--; // go backward + return[c, d - c, e - c] // return position and lengths of the two substrings found + }, + + // Update preview window content updatePreviewWindow: function(thisCM,filepath,filename,fileExt) { if (top.ICEcoder.previewWindow.location.pathname==filepath) {