diff --git a/lib/model/content.dart b/lib/model/content.dart index 804cfb6d1a..0b0bb502bb 100644 --- a/lib/model/content.dart +++ b/lib/model/content.dart @@ -639,7 +639,11 @@ class _ZulipContentParser { return RegExp("^(?:$mentionClass(?: silent)?|silent $mentionClass)\$"); }(); - static final _emojiClassRegexp = RegExp(r"^emoji(?:-[0-9a-f]+)*$"); + static final _emojiClassNameRegexp = () { + const specificEmoji = r"emoji(?:-[0-9a-f]+)+"; + return RegExp("^(?:emoji $specificEmoji|$specificEmoji emoji)\$"); + }(); + static final _emojiCodeFromClassNameRegexp = RegExp(r"emoji-([^ ]+)"); InlineContentNode parseInlineContent(dom.Node node) { assert(_debugParserContext == _ParserContext.inline); @@ -655,7 +659,6 @@ class _ZulipContentParser { final element = node; final localName = element.localName; - final classes = element.classes; final className = element.className; List nodes() => parseInlineContentList(element.nodes); @@ -691,14 +694,9 @@ class _ZulipContentParser { } if (localName == 'span' - && classes.length == 2 - && classes.contains('emoji') - && classes.every(_emojiClassRegexp.hasMatch)) { - final emojiCode = classes - .firstWhere((className) => className.startsWith('emoji-')) - .replaceFirst('emoji-', ''); - assert(emojiCode.isNotEmpty); - + && _emojiClassNameRegexp.hasMatch(className)) { + final emojiCode = _emojiCodeFromClassNameRegexp.firstMatch(className)! + .group(1)!; final unicode = tryParseEmojiCodeToUnicode(emojiCode); if (unicode == null) return unimplemented(); return UnicodeEmojiNode(emojiUnicode: unicode, debugHtmlNode: debugHtmlNode); diff --git a/test/model/content_test.dart b/test/model/content_test.dart index 5805f5e22c..dc97c89b92 100644 --- a/test/model/content_test.dart +++ b/test/model/content_test.dart @@ -166,6 +166,11 @@ void main() { '

:thumbs_up:

', const UnicodeEmojiNode(emojiUnicode: '\u{1f44d}')); // "👍" + testParseInline('parse Unicode emoji, encoded in span element, class order reversed', + // ":thumbs_up:" (hypothetical server variation) + '

:thumbs_up:

', + const UnicodeEmojiNode(emojiUnicode: '\u{1f44d}')); // "👍" + testParseInline('parse Unicode emoji, encoded in span element, multiple codepoints', // ":transgender_flag:" '

:transgender_flag:

',