]>
cat aescling's git repositories - mastodon.git/blob - app/javascript/mastodon/features/emoji/emoji.js
359bb7ffd44700b28eb21682eff00d57beda8dcc
1 import { autoPlayGif
} from '../../initial_state';
2 import unicodeMapping
from './emoji_unicode_mapping_light';
3 import Trie
from 'substring-trie';
5 const trie
= new Trie(Object
.keys(unicodeMapping
));
7 const assetHost
= process
.env
.CDN_HOST
|| '';
9 const emojify
= (str
, customEmojis
= {}) => {
10 const tagCharsWithoutEmojis
= '<&';
11 const tagCharsWithEmojis
= Object
.keys(customEmojis
).length
? '<&:' : '<&';
12 let rtn
= '', tagChars
= tagCharsWithEmojis
, invisible
= 0;
14 let match
, i
= 0, tag
;
15 while (i
< str
.length
&& (tag
= tagChars
.indexOf(str
[i
])) === -1 && (invisible
|| !(match
= trie
.search(str
.slice(i
))))) {
16 i
+= str
.codePointAt(i
) < 65536 ? 1 : 2;
18 let rend
, replacement
= '';
19 if (i
=== str
.length
) {
21 } else if (str
[i
] === ':') {
23 rend
= str
.indexOf(':', i
+ 1) + 1;
24 if (!rend
) return false; // no pair of ':'
25 const lt
= str
.indexOf('<', i
+ 1);
26 if (!(lt
=== -1 || lt
>= rend
)) return false; // tag appeared before closing ':'
27 const shortname
= str
.slice(i
, rend
);
28 // now got a replacee as ':shortname:'
29 // if you want additional emoji handler, add statements below which set replacement and return true.
30 if (shortname
in customEmojis
) {
31 const filename
= autoPlayGif
? customEmojis
[shortname
].url : customEmojis
[shortname
].static_url
;
32 replacement
= `<img draggable="false" class="emojione custom-emoji" alt="${shortname}" title="${shortname}" src="${filename}" data-original="${customEmojis[shortname].url}" data-static="${customEmojis[shortname].static_url}" />`;
37 } else if (tag
>= 0) { // <, &
38 rend
= str
.indexOf('>;'[tag
], i
+ 1) + 1;
44 if (str
[i
+ 1] === '/') { // closing tag
46 tagChars
= tagCharsWithEmojis
;
48 } else if (str
[rend
- 2] !== '/') { // opening tag
52 if (str
.startsWith('<span class="invisible">', i
)) {
53 // avoid emojifying on invisible text
55 tagChars
= tagCharsWithoutEmojis
;
60 } else { // matched to unicode emoji
61 const { filename
, shortCode
} = unicodeMapping
[match
];
62 const title
= shortCode
? `:${shortCode}:` : '';
63 replacement
= `<img draggable="false" class="emojione" alt="${match}" title="${title}" src="${assetHost}/emoji/${filename}.svg" />`;
64 rend
= i
+ match
.length
;
65 // If the matched character was followed by VS15 (for selecting text presentation), skip it.
66 if (str
.codePointAt(rend
) === 65038) {
70 rtn
+= str
.slice(0, i
) + replacement
;
71 str
= str
.slice(rend
);
76 export default emojify
;
78 export const buildCustomEmojis
= (customEmojis
) => {
81 customEmojis
.forEach(emoji
=> {
82 const shortcode
= emoji
.get('shortcode');
83 const url
= autoPlayGif
? emoji
.get('url') : emoji
.get('static_url');
84 const name
= shortcode
.replace(':', '');
95 customCategory: emoji
.get('category'),
102 export const categoriesFromEmojis
= customEmojis
=> customEmojis
.reduce((set, emoji
) => set.add(emoji
.get('category') ? `custom-${emoji.get('category')}` : 'custom'), new Set());
This page took 0.093555 seconds and 2 git commands to generate.