Sfoglia il codice sorgente

Updated fastDiff code comment. Added test for replacing emoji with another emoji.

Kuba Niegowski 5 anni fa
parent
commit
7156091ddb

+ 6 - 2
packages/ckeditor5-utils/src/fastdiff.js

@@ -100,8 +100,12 @@ export default function fastDiff( a, b, cmp, atomicChanges = false ) {
 		return a === b;
 	};
 
-	// Transform text or any iterable into arrays for easier, consistent processing.
-	// Array.from was used here but it generated incorrect results for multi-byte unicode sequences.
+	// Convert the string (or any array-like object - eg. NodeList) to an array by using the slice() method because,
+	// unlike Array.from(), it returns array of UTF-16 code units instead of the code points of a string.
+	// One code point might be a surrogate pair of two code units. All text offsets are expected to be in code units.
+	// See ckeditor/ckeditor5#3147.
+	//
+	// We need to make sure here that fastDiff() works identical to diff().
 	if ( !Array.isArray( a ) ) {
 		a = Array.prototype.slice.call( a );
 	}

+ 8 - 0
packages/ckeditor5-utils/tests/diff.js

@@ -99,6 +99,14 @@ describe( 'diff', () => {
 			it( 'should properly replace emoji', () => {
 				expect( diff( 'a🙂b', 'axb' ) ).to.deep.equal( [ 'equal', ...emojiDiffDelete, 'insert', 'equal' ] );
 			} );
+
+			it( 'should properly replace one emoji with another', () => {
+				// 😄 = '\ud83d\ude04' = 2 chars
+				// Note both emoji have same first code unit
+				expect( diff( 'a🙂b', 'a😄b' ) ).to.deep.equal(
+					[ 'equal', 'equal', ...emojiDiffInsert.slice( 1 ), ...emojiDiffDelete.slice( 1 ), 'equal' ]
+				);
+			} );
 		} );
 
 		describe( 'combined emoji - unicode ZWJ sequence', () => {