Fix emoji replacement in composer

* Re-scan the slate document tree on each emoji replacement since
   doing a replacement will invalidate all the offsets we have.
 * Reset the emoji regex each time we use it.

Fixes https://github.com/vector-im/riot-web/issues/7550
pull/21833/head
David Baker 2018-10-24 16:46:06 +01:00
parent 4c3c8a6285
commit 78d8d22457
1 changed files with 35 additions and 21 deletions

View File

@ -573,29 +573,43 @@ export default class MessageComposerInput extends React.Component {
} }
// emojioneify any emoji // emojioneify any emoji
editorState.document.getTexts().forEach(node => { while (true) {
if (node.text !== '' && HtmlUtils.containsEmoji(node.text)) { let foundEmoji = false;
let match;
while ((match = EMOJI_REGEX.exec(node.text)) !== null) { for (const node of editorState.document.getTexts()) {
const range = Range.create({ if (node.text !== '' && HtmlUtils.containsEmoji(node.text)) {
anchor: { let match;
key: node.key, EMOJI_REGEX.lastIndex = 0;
offset: match.index, while ((match = EMOJI_REGEX.exec(node.text)) !== null) {
}, const range = Range.create({
focus: { anchor: {
key: node.key, key: node.key,
offset: match.index + match[0].length, offset: match.index,
}, },
}); focus: {
const inline = Inline.create({ key: node.key,
type: 'emoji', offset: match.index + match[0].length,
data: { emojiUnicode: match[0] }, },
}); });
change = change.insertInlineAtRange(range, inline); const inline = Inline.create({
editorState = change.value; type: 'emoji',
data: { emojiUnicode: match[0] },
});
change = change.insertInlineAtRange(range, inline);
editorState = change.value;
// if we replaced an emoji, start again looking for more
// emoji in the new editor state since doing the replacement
// will change the node structure & offsets so we can't compute
// insertion ranges from node.key / match.index anymore.
foundEmoji = true;
break;
}
} }
} }
});
if (!foundEmoji) break;
}
// work around weird bug where inserting emoji via the macOS // work around weird bug where inserting emoji via the macOS
// emoji picker can leave the selection stuck in the emoji's // emoji picker can leave the selection stuck in the emoji's