diff options
Diffstat (limited to 'node_modules/fast-diff/diff.js')
-rw-r--r-- | node_modules/fast-diff/diff.js | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/node_modules/fast-diff/diff.js b/node_modules/fast-diff/diff.js index c6e3f3ddd..a2dfb4d09 100644 --- a/node_modules/fast-diff/diff.js +++ b/node_modules/fast-diff/diff.js @@ -82,6 +82,7 @@ function diff_main(text1, text2, cursor_pos) { if (cursor_pos != null) { diffs = fix_cursor(diffs, cursor_pos); } + diffs = fix_emoji(diffs); return diffs; }; @@ -671,7 +672,46 @@ function fix_cursor (diffs, cursor_pos) { return diffs; } } +} + +/* + * Check diff did not split surrogate pairs. + * Ex. [0, '\uD83D'], [-1, '\uDC36'], [1, '\uDC2F'] -> [-1, '\uD83D\uDC36'], [1, '\uD83D\uDC2F'] + * '\uD83D\uDC36' === '🐶', '\uD83D\uDC2F' === '🐯' + * + * @param {Array} diffs Array of diff tuples + * @return {Array} Array of diff tuples + */ +function fix_emoji (diffs) { + var compact = false; + var starts_with_pair_end = function(str) { + return str.charCodeAt(0) >= 0xDC00 && str.charCodeAt(0) <= 0xDFFF; + } + var ends_with_pair_start = function(str) { + return str.charCodeAt(str.length-1) >= 0xD800 && str.charCodeAt(str.length-1) <= 0xDBFF; + } + for (var i = 2; i < diffs.length; i += 1) { + if (diffs[i-2][0] === DIFF_EQUAL && ends_with_pair_start(diffs[i-2][1]) && + diffs[i-1][0] === DIFF_DELETE && starts_with_pair_end(diffs[i-1][1]) && + diffs[i][0] === DIFF_INSERT && starts_with_pair_end(diffs[i][1])) { + compact = true; + + diffs[i-1][1] = diffs[i-2][1].slice(-1) + diffs[i-1][1]; + diffs[i][1] = diffs[i-2][1].slice(-1) + diffs[i][1]; + diffs[i-2][1] = diffs[i-2][1].slice(0, -1); + } + } + if (!compact) { + return diffs; + } + var fixed_diffs = []; + for (var i = 0; i < diffs.length; i += 1) { + if (diffs[i][1].length > 0) { + fixed_diffs.push(diffs[i]); + } + } + return fixed_diffs; } /* |