mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
fix(app): keep a backslash-escaped emoji literal in the composer (#2006)
This commit is contained in:
1 parent
78f7db9250
commit
fa99ec6f8f
1 file changed
+34
-4
@@ -41,16 +41,30 @@ function findUnicodeEmoji(text: string, startIndex: number): TypedEmojiMatch | n
|
||||
return {start: match.index, end: match.index + match[0].length, name};
|
||||
}
|
||||
|
||||
function findNextEmojiToken(text: string, startIndex: number): TypedEmojiMatch | null {
|
||||
interface EmojiToken extends TypedEmojiMatch {
|
||||
surrogate: boolean;
|
||||
}
|
||||
|
||||
function findNextEmojiToken(text: string, startIndex: number): EmojiToken | null {
|
||||
const shortcode = findTypedEmojiShortcode(text, startIndex);
|
||||
const surrogate = findUnicodeEmoji(text, startIndex);
|
||||
if (shortcode == null) {
|
||||
return surrogate;
|
||||
return surrogate == null ? null : {...surrogate, surrogate: true};
|
||||
}
|
||||
if (surrogate == null) {
|
||||
return shortcode;
|
||||
return {...shortcode, surrogate: false};
|
||||
}
|
||||
return surrogate.start < shortcode.start ? surrogate : shortcode;
|
||||
return surrogate.start < shortcode.start ? {...surrogate, surrogate: true} : {...shortcode, surrogate: false};
|
||||
}
|
||||
|
||||
function isEscapedAt(text: string, index: number): boolean {
|
||||
let backslashes = 0;
|
||||
let cursor = index - 1;
|
||||
while (cursor >= 0 && text[cursor] === '\\') {
|
||||
backslashes += 1;
|
||||
cursor -= 1;
|
||||
}
|
||||
return backslashes % 2 === 1;
|
||||
}
|
||||
|
||||
export function $convertEmojiShortcode(node: TextNode, resolve: ComposerEmojiResolver): void {
|
||||
@@ -72,6 +86,22 @@ export function $convertEmojiShortcode(node: TextNode, resolve: ComposerEmojiRes
|
||||
if ((codeMarkers == null ? 0 : codeMarkers.length) % 2 === 1) {
|
||||
return;
|
||||
}
|
||||
if (isEscapedAt(text, match.start)) {
|
||||
if (match.surrogate) {
|
||||
const shortcodeText = `:${match.name}:`;
|
||||
const selection = $captureSelectionOffsets();
|
||||
const nodeDisplayStart = $getComposerNodeDisplayStart(node);
|
||||
const replaced = `${text.slice(0, match.start)}${shortcodeText}${text.slice(match.end)}`;
|
||||
node.setTextContent(replaced);
|
||||
if (selection != null) {
|
||||
const adjusted = $adjustEmbedCaret(selection, nodeDisplayStart, match.start, match.end, shortcodeText.length);
|
||||
$selectComposerRange(adjusted.anchor, adjusted.focus);
|
||||
}
|
||||
return;
|
||||
}
|
||||
searchFrom = match.end;
|
||||
continue;
|
||||
}
|
||||
const previous = match.start === 0 ? node.getPreviousSibling() : null;
|
||||
if (/^skin-tone-[1-5]$/.test(match.name) && $isComposerStandardEmojiNode(previous)) {
|
||||
const baseName = previous.getEmojiName().split('::')[0]!;
|
||||
|
||||
Reference in new issue
Block a user