This repository has been archived by the owner on Mar 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
emoticons.tsx
92 lines (77 loc) · 2.99 KB
/
emoticons.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
export const emoticonPatterns: { [key: string]: RegExp } = {
slightly_smiling_face: /(^|\B)(:-?\))($|\B)/g, // :)
wink: /(^|\B)(;-?\))($|\B)/g, // ;)
open_mouth: /(^|\B)(:o)($|\b)/gi, // :o
scream: /(^|\B)(:-o)($|\b)/gi, // :-o
smirk: /(^|\B)(:-?])($|\B)/g, // :]
smile: /(^|\B)(:-?d)($|\b)/gi, // :D
stuck_out_tongue_closed_eyes: /(^|\b)(x-d)($|\b)/gi, // x-d
stuck_out_tongue: /(^|\B)(:-?p)($|\b)/gi, // :p
rage: /(^|\B)(:-?[[@])($|\B)/g, // :@
slightly_frowning_face: /(^|\B)(:-?\()($|\B)/g, // :(
cry: /(^|\B)(:[`'’]-?\(|:'\(|:'\()($|\B)/g, // :`(
confused: /(^|\B)(:-?\/)($|\B)/g, // :/
confounded: /(^|\B)(:-?s)($|\b)/gi, // :s
neutral_face: /(^|\B)(:-?\|)($|\B)/g, // :|
flushed: /(^|\B)(:-?\$)($|\B)/g, // :$
mask: /(^|\B)(:-x)($|\b)/gi, // :-x
heart: /(^|\B)(<3|<3)($|\b)/g, // <3
broken_heart: /(^|\B)(<\/3|<\/3)($|\b)/g, // </3
thumbsup: /(^|\B)(:\+1:)($|\B)/g, // :+1:
thumbsdown: /(^|\B)(:-1:)($|\B)/g, // :-1:
};
export const EMOJI_PATTERN = /(:([a-zA-Z0-9_-]+):)/g;
export function matchEmoticons(text: string): RegExpMatchArray | null {
let emojis = text.match(EMOJI_PATTERN);
for (const name of Object.keys(emoticonPatterns)) {
const pattern = emoticonPatterns[name];
const matches = text.match(pattern);
if (matches) {
if (emojis) {
emojis = emojis.concat(matches);
} else {
emojis = matches;
}
}
}
return emojis;
}
export function handleEmoticons(
text: string,
tokens: Map<string, {value: string; originalText: string}>,
): string {
let output = text;
function replaceEmoticonWithToken(
fullMatch: string,
prefix: string,
matchText: string,
name: string,
): string {
const index = tokens.size;
const alias = `$MM_EMOTICON${index}$`;
tokens.set(alias, {
value: renderEmoji(name, matchText),
originalText: fullMatch,
});
return prefix + alias;
}
// match named emoticons like :goat:
output = output.replace(
EMOJI_PATTERN,
(fullMatch: string, matchText: string, name: string): string =>
replaceEmoticonWithToken(fullMatch, '', matchText, name),
);
// match text smilies like :D
for (const name of Object.keys(emoticonPatterns)) {
const pattern = emoticonPatterns[name];
// this might look a bit funny, but since the name isn't contained in the actual match
// like with the named emoticons, we need to add it in manually
output = output.replace(pattern, (fullMatch, prefix, matchText) => replaceEmoticonWithToken(fullMatch, prefix, matchText, name));
}
return output;
}
export function renderEmoji(name: string, matchText: string) {
return `<span data-emoticon="${name}">${matchText}</span>`;
}