Skip to content

Commit

Permalink
Исправил восстановление данных эмоджи после токена ссылки
Browse files Browse the repository at this point in the history
  • Loading branch information
rvrhiv committed Dec 13, 2023
1 parent e0fa231 commit 907f884
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/formatted-string/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { mdToText, textToMd } from './markdown';
import type { TokenFormatUpdate, TextRange, CutText, EmojiUpdatePayload } from './types';
import {
tokenForPos, isSolidToken, isCustomLink, isAutoLink, splitToken,
sliceToken, toLink, toText, tokenRange, createToken, createEmojiUpdatePayload
sliceToken, toLink, toText, tokenRange, createToken, createEmojiUpdatePayload, TokenForPos
} from './utils';
import { objectMerge } from '../utils/objectMerge';
import type { Emoji } from '../parser/types';
Expand Down Expand Up @@ -313,8 +313,9 @@ export function updateEmojiData(tokens: Token[], payload: EmojiUpdatePayload[]):
* @param endToken токен в котором был конец вставки (может быть равен `startToken`)
* @param endOffset в какую позицию была вставка относительно текста `endToken`
* @param textBound длина нового текста без учета `endToken.value` (после `endOffset`)
* @param tokensOffsetBeforeStart смещение для эмоджи в startToken
*/
function saveEmojiDataForUpdate(tokens: Token[], startToken: Token, startOffset: number, endToken: Token, endOffset: number, textBound: number) {
function saveEmojiDataForUpdate(tokens: Token[], startToken: Token, startOffset: number, endToken: Token, endOffset: number, textBound: number, tokensOffsetBeforeStart = 0) {
// собираем эмоджи из startToken до startOffset
const startTokenEmojis: Emoji[] = [];
for (let index = 0; index < startToken.emoji?.length || 0; index++) {
Expand All @@ -325,7 +326,7 @@ function saveEmojiDataForUpdate(tokens: Token[], startToken: Token, startOffset:
break;
}
}
const startTokenEmojiPayload = createEmojiUpdatePayload(startTokenEmojis, 0, startToken.value);
const startTokenEmojiPayload = createEmojiUpdatePayload(startTokenEmojis, tokensOffsetBeforeStart, startToken.value);

// собираем эмоджи из endToken после endOffset
const endTokenEmojis: Emoji[] = [];
Expand Down Expand Up @@ -373,6 +374,12 @@ function updateTokens(tokens: Token[], value: string, from: number, to: number,
let nextValue = startToken.value.slice(0, start.offset)
+ value + endToken.value.slice(end.offset);

// сохраняем startToken, чтобы правильно восстановить данные эмоджи
// при пограничном случае с автоссылкой
const startForEmoji: TokenForPos = { ...start };
const startTokenForEmoji = startToken;
let startOffsetForEmoji = 0;

// Разбираем пограничный случай: есть автоссылка `mail.ru`, мы дописали в конец
// `?` – вопрос останется текстом, так как это знак препинания в конце предложения.
// Но если продолжим писать текст, например, `foo`, то `mail.ru?foo` должен
Expand All @@ -384,6 +391,7 @@ function updateTokens(tokens: Token[], value: string, from: number, to: number,
textBound += startToken.value.length;
start.index--;
start.offset = 0;
startOffsetForEmoji = startToken.value.length;
}

let nextTokens = parse(nextValue, options);
Expand All @@ -394,7 +402,7 @@ function updateTokens(tokens: Token[], value: string, from: number, to: number,

// переносим параметры эмоджи из startToken (до start.offset) и endToken (после end.offset),
// так как после parse() эти параметры теряются
nextTokens = saveEmojiDataForUpdate(nextTokens, startToken, start.offset, endToken, end.offset, textBound);
nextTokens = saveEmojiDataForUpdate(nextTokens, startTokenForEmoji, startForEmoji.offset, endToken, end.offset, textBound, startOffsetForEmoji);

// Применяем форматирование из концевых токенов, но только если можем
// сделать это безопасно: применяем только для текста
Expand Down

0 comments on commit 907f884

Please sign in to comment.