mirror of
https://github.com/block/buzz.git
synced 2026-11-06 01:11:33 +00:00
fix(desktop): highlight full multi-word display names in composer ove… (#163)
This commit is contained in:
23
desktop/src/shared/lib/mentionPattern.ts
Normal file
23
desktop/src/shared/lib/mentionPattern.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Escape special regex characters in a string.
|
||||
*/
|
||||
export function escapeRegExp(str: string): string {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a regex that matches @mentions, trying known multi-word names first
|
||||
* (longest-first to avoid partial matches), then falling back to @\S+.
|
||||
*/
|
||||
export function buildMentionPattern(mentionNames: string[]): RegExp {
|
||||
const sorted = [...new Set(mentionNames)]
|
||||
.filter((name) => name.trim().length > 0)
|
||||
.sort((a, b) => b.length - a.length);
|
||||
|
||||
if (sorted.length === 0) {
|
||||
return /@\S+/g;
|
||||
}
|
||||
|
||||
const nameAlternatives = sorted.map((name) => escapeRegExp(name)).join("|");
|
||||
return new RegExp(`@(?:${nameAlternatives}|\\S+)`, "g");
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
* falls back to the generic `@\S+` pattern for unknown mentions.
|
||||
*/
|
||||
|
||||
import { buildMentionPattern } from "./mentionPattern";
|
||||
|
||||
type RemarkMentionsOptions = {
|
||||
mentionNames?: string[];
|
||||
};
|
||||
@@ -42,25 +44,6 @@ function walkChildren(node: any, mentionPattern: RegExp) {
|
||||
}
|
||||
}
|
||||
|
||||
function escapeRegExp(str: string): string {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
function buildMentionPattern(mentionNames: string[]): RegExp {
|
||||
// Deduplicate and sort longest-first so "John Doe" is matched before "John"
|
||||
const sorted = [...new Set(mentionNames)]
|
||||
.filter((name) => name.trim().length > 0)
|
||||
.sort((a, b) => b.length - a.length);
|
||||
|
||||
if (sorted.length === 0) {
|
||||
return /@\S+/g;
|
||||
}
|
||||
|
||||
// Build alternation: try known names first, then fall back to @\S+
|
||||
const nameAlternatives = sorted.map((name) => escapeRegExp(name)).join("|");
|
||||
return new RegExp(`@(?:${nameAlternatives}|\\S+)`, "g");
|
||||
}
|
||||
|
||||
function splitMentions(text: string, mentionPattern: RegExp) {
|
||||
// Reset lastIndex — the pattern is reused across text nodes with the `g` flag
|
||||
mentionPattern.lastIndex = 0;
|
||||
|
||||
Reference in New Issue
Block a user