diff --git a/frontend_tests/node_tests/util.js b/frontend_tests/node_tests/util.js index 30c6153d61..a3f59c19a5 100644 --- a/frontend_tests/node_tests/util.js +++ b/frontend_tests/node_tests/util.js @@ -303,3 +303,15 @@ run_test("filter_by_word_prefix_match", () => { ]); assert.deepEqual(util.filter_by_word_prefix_match(values, "unders", item_to_string, /\s/), []); }); + +run_test("get_string_diff", () => { + assert.deepEqual( + util.get_string_diff("#ann is for updates", "#**announce** is for updates"), + [1, 4, 13], + ); + assert.deepEqual(util.get_string_diff("/p", "/poll"), [2, 2, 5]); + assert.deepEqual(util.get_string_diff("Hey @Aa", "Hey @**aaron** "), [5, 7, 15]); + assert.deepEqual(util.get_string_diff("same", "same"), [0, 0, 0]); + assert.deepEqual(util.get_string_diff("same-end", "two same-end"), [0, 0, 4]); + assert.deepEqual(util.get_string_diff("space", "sp ace"), [2, 2, 3]); +}); diff --git a/static/js/util.ts b/static/js/util.ts index d7ad5a51fe..b46ab30c88 100644 --- a/static/js/util.ts +++ b/static/js/util.ts @@ -402,3 +402,42 @@ export function call_function_periodically(callback: () => void, delay: number): callback(); } + +export function get_string_diff(string1: string, string2: string): [number, number, number] { + // This function specifies the single minimal diff between 2 strings. For + // example, the diff between "#ann is for updates" and "#**announce** is + // for updates" is from index 1, till 4 in the 1st string and 13 in the + // 2nd string; + + let diff_start_index = -1; + for (let i = 0; i < Math.min(string1.length, string2.length); i += 1) { + if (string1.charAt(i) === string2.charAt(i)) { + diff_start_index = i; + } else { + break; + } + } + diff_start_index += 1; + + if (string1.length === string2.length && string1.length === diff_start_index) { + // if the 2 strings are identical + return [0, 0, 0]; + } + + let diff_end_1_index = string1.length; + let diff_end_2_index = string2.length; + for ( + let i = string1.length - 1, j = string2.length - 1; + i >= diff_start_index && j >= diff_start_index; + i -= 1, j -= 1 + ) { + if (string1.charAt(i) === string2.charAt(j)) { + diff_end_1_index = i; + diff_end_2_index = j; + } else { + break; + } + } + + return [diff_start_index, diff_end_1_index, diff_end_2_index]; +}