@@ -82,6 +82,7 @@ function diff_main(text1, text2, cursor_pos) {
82
82
if ( cursor_pos != null ) {
83
83
diffs = fix_cursor ( diffs , cursor_pos ) ;
84
84
}
85
+ diffs = fix_emoji ( diffs ) ;
85
86
return diffs ;
86
87
} ;
87
88
@@ -671,7 +672,46 @@ function fix_cursor (diffs, cursor_pos) {
671
672
return diffs ;
672
673
}
673
674
}
675
+ }
676
+
677
+ /*
678
+ * Check diff did not split surrogate pairs.
679
+ * Ex. [0, '\uD83D'], [-1, '\uDC36'], [1, '\uDC2F'] -> [-1, '\uD83D\uDC36'], [1, '\uD83D\uDC2F']
680
+ * '\uD83D\uDC36' === 'πΆ', '\uD83D\uDC2F' === 'π―'
681
+ *
682
+ * @param {Array } diffs Array of diff tuples
683
+ * @return {Array } Array of diff tuples
684
+ */
685
+ function fix_emoji ( diffs ) {
686
+ var compact = false ;
687
+ var starts_with_pair_end = function ( str ) {
688
+ return str . charCodeAt ( 0 ) >= 0xDC00 && str . charCodeAt ( 0 ) <= 0xDFFF ;
689
+ }
690
+ var ends_with_pair_start = function ( str ) {
691
+ return str . charCodeAt ( str . length - 1 ) >= 0xD800 && str . charCodeAt ( str . length - 1 ) <= 0xDBFF ;
692
+ }
693
+ for ( var i = 2 ; i < diffs . length ; i += 1 ) {
694
+ if ( diffs [ i - 2 ] [ 0 ] === DIFF_EQUAL && ends_with_pair_start ( diffs [ i - 2 ] [ 1 ] ) &&
695
+ diffs [ i - 1 ] [ 0 ] === DIFF_DELETE && starts_with_pair_end ( diffs [ i - 1 ] [ 1 ] ) &&
696
+ diffs [ i ] [ 0 ] === DIFF_INSERT && starts_with_pair_end ( diffs [ i ] [ 1 ] ) ) {
697
+ compact = true ;
698
+
699
+ diffs [ i - 1 ] [ 1 ] = diffs [ i - 2 ] [ 1 ] . slice ( - 1 ) + diffs [ i - 1 ] [ 1 ] ;
700
+ diffs [ i ] [ 1 ] = diffs [ i - 2 ] [ 1 ] . slice ( - 1 ) + diffs [ i ] [ 1 ] ;
674
701
702
+ diffs [ i - 2 ] [ 1 ] = diffs [ i - 2 ] [ 1 ] . slice ( 0 , - 1 ) ;
703
+ }
704
+ }
705
+ if ( ! compact ) {
706
+ return diffs ;
707
+ }
708
+ var fixed_diffs = [ ] ;
709
+ for ( var i = 0 ; i < diffs . length ; i += 1 ) {
710
+ if ( diffs [ i ] [ 1 ] . length > 0 ) {
711
+ fixed_diffs . push ( diffs [ i ] ) ;
712
+ }
713
+ }
714
+ return fixed_diffs ;
675
715
}
676
716
677
717
/*
0 commit comments