diff --git a/packages/shared/src/threadSearch.test.ts b/packages/shared/src/threadSearch.test.ts index 83b87841c789a..fb52b2ec16a29 100644 --- a/packages/shared/src/threadSearch.test.ts +++ b/packages/shared/src/threadSearch.test.ts @@ -12,3 +12,8 @@ it("matches both Greek sigma forms without changing source offsets", () => { expect(findThreadSearchOccurrences("ΟΣ ος οσ", "ς")).toEqual([1, 4, 7]); expect(findThreadSearchOccurrences("İ ΟΣ", "Σ")).toEqual([3]); }); + +it("matches straight and curly apostrophes without changing source offsets", () => { + expect(findThreadSearchOccurrences("don't don’t", "don’t")).toEqual([0, 6]); + expect(findThreadSearchOccurrences("İ don‘t", "don't")).toEqual([2]); +}); diff --git a/packages/shared/src/threadSearch.ts b/packages/shared/src/threadSearch.ts index 5cca036d7bed4..6ffa12fcc1523 100644 --- a/packages/shared/src/threadSearch.ts +++ b/packages/shared/src/threadSearch.ts @@ -1,10 +1,13 @@ +// A typed straight apostrophe finds a curly one: iOS keyboards type "’". +const foldCharacters = (text: string) => text.replace(/ς/g, "σ").replace(/[‘’]/g, "'"); + function foldThreadSearchCase(text: string): string { - const lowered = text.toLowerCase().replace(/ς/g, "σ"); + const lowered = foldCharacters(text.toLowerCase()); if (lowered.length === text.length) return lowered; let folded = ""; for (const character of text) { - const loweredCharacter = character.toLowerCase().replace(/ς/g, "σ"); + const loweredCharacter = foldCharacters(character.toLowerCase()); folded += loweredCharacter.length === character.length ? loweredCharacter : character; } return folded;