From 941f3048f6a749185468ab4e94013bf7d1e885e1 Mon Sep 17 00:00:00 2001 From: spoukyii <61633921+spoukyii@users.noreply.github.com> Date: Tue, 3 Nov 2026 11:59:21 -0800 Subject: [PATCH 1/2] test(web): a preview annotation chip label cut beside an emoji The chip label of a preview annotation cuts a long comment at 47 UTF-16 code units. When an emoji straddles that cut, the label keeps half of it and shows a replacement character before the ellipsis, and this test fails here. --- apps/web/src/lib/composerContextRecords.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/web/src/lib/composerContextRecords.test.ts b/apps/web/src/lib/composerContextRecords.test.ts index f612a302ac8c8..95a14d469c962 100644 --- a/apps/web/src/lib/composerContextRecords.test.ts +++ b/apps/web/src/lib/composerContextRecords.test.ts @@ -218,6 +218,14 @@ describe("composerContextRecords", () => { expect(image).toMatchObject({ attachmentId: "uploaded-image" }); }); + it("shortens a long annotation comment label without splitting an emoji", () => { + const record = previewAnnotationContextRecord({ + ...annotation, + comment: `${"a".repeat(46)}😀 and make the button bigger`, + }); + expect(record.label).toBe(`${"a".repeat(46)}…`); + }); + it("restores multiple edits on one target without parsing display strings", () => { const styleChanges = [ ...annotation.styleChanges, From 4c16851fb07297156d6f28d65edf9cccee885911 Mon Sep 17 00:00:00 2001 From: spoukyii <61633921+spoukyii@users.noreply.github.com> Date: Tue, 3 Nov 2026 12:00:36 -0800 Subject: [PATCH 2/2] fix(web): preview annotation chip labels no longer end in a broken character A preview annotation's context chip takes its label from the comment, cut at 47 UTF-16 code units before the shared label sanitizer runs. An emoji straddling that cut left a lone high surrogate before the ellipsis, so the chip, the record sent with the message and a thread title seeded from the annotation all showed a replacement character. The cut now steps back one unit when it would split a surrogate pair, the check #29158 added to the shared context chip label cap. The 48-character limit and labels without a split emoji are unchanged. Bug: a preview annotation chip label ends in a broken character when an emoji sits at the cut --- apps/web/src/lib/composerContextRecords.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/web/src/lib/composerContextRecords.ts b/apps/web/src/lib/composerContextRecords.ts index c4f123f73dcc4..3f5c6c1da19a0 100644 --- a/apps/web/src/lib/composerContextRecords.ts +++ b/apps/web/src/lib/composerContextRecords.ts @@ -110,9 +110,12 @@ export function pullRequestContextKindLabel(comment: ReviewCommentPresentation): export function previewAnnotationContextLabel(annotation: PreviewAnnotationPayload): string { const comment = annotation.comment.trim().replace(/\s+/g, " "); if (comment) { - return comment.length > PREVIEW_LABEL_MAX_CHARS - ? `${comment.slice(0, PREVIEW_LABEL_MAX_CHARS - 1)}…` - : comment; + if (comment.length <= PREVIEW_LABEL_MAX_CHARS) return comment; + let end = PREVIEW_LABEL_MAX_CHARS - 1; + const previous = comment.charCodeAt(end - 1); + const next = comment.charCodeAt(end); + if (previous >= 0xd800 && previous <= 0xdbff && next >= 0xdc00 && next <= 0xdfff) end -= 1; + return `${comment.slice(0, end)}…`; } return annotation.pageTitle?.trim() || "Preview annotation"; }