import { autoPlayGif, useSystemEmojiFont } from 'flavours/glitch/initial_state'; import unicodeMapping from './emoji_unicode_mapping_light'; import { assetHost } from 'flavours/glitch/util/config'; import Trie from 'substring-trie'; const trie = new Trie(Object.keys(unicodeMapping)); // Convert to file names from emojis. (For different variation selector emojis) const emojiFilenames = (emojis) => { return emojis.map(v => unicodeMapping[v].filename); }; // Emoji requiring extra borders depending on theme const darkEmoji = emojiFilenames(['🎱', '🐜', 'âšĢ', '🖤', 'âŦ›', 'â—ŧī¸', '◾', 'â—ŧī¸', '✒ī¸', 'â–Ēī¸', 'đŸ’Ŗ', 'đŸŽŗ', '📷', '📸', 'â™Ŗī¸', 'đŸ•ļī¸', '✴ī¸', '🔌', '💂‍♀ī¸', 'đŸ“Ŋī¸', 'đŸŗ', 'đŸĻ', '💂', 'đŸ”Ē', 'đŸ•ŗī¸', '🕹ī¸', '🕋', '🖊ī¸', '🖋ī¸', '💂‍♂ī¸', '🎤', '🎓', 'đŸŽĨ', 'đŸŽŧ', '♠ī¸', '🎩', 'đŸĻƒ', 'đŸ“ŧ', '📹', '🎮', '🐃', '🏴', '🐞', 'đŸ•ē', '📱', '📲', '🚲']); const lightEmoji = emojiFilenames(['đŸ‘Ŋ', '⚾', '🐔', '☁ī¸', '💨', '🕊ī¸', '👀', 'đŸĨ', 'đŸ‘ģ', '🐐', '❕', '❔', '⛸ī¸', '🌩ī¸', '🔊', '🔇', '📃', '🌧ī¸', '🐏', '🍚', '🍙', '🐓', '🐑', '💀', '☠ī¸', '🌨ī¸', '🔉', '🔈', 'đŸ’Ŧ', '💭', '🏐', 'đŸŗī¸', 'âšĒ', 'âŦœ', 'â—Ŋ', 'â—ģī¸', 'â–Ģī¸']); const emojiFilename = (filename) => { const borderedEmoji = (document.body && document.body.classList.contains('skin-mastodon-light')) ? lightEmoji : darkEmoji; return borderedEmoji.includes(filename) ? (filename + '_border') : filename; }; const emojify = (str, customEmojis = {}) => { const tagCharsWithoutEmojis = '<&'; const tagCharsWithEmojis = Object.keys(customEmojis).length ? '<&:' : '<&'; let rtn = '', tagChars = tagCharsWithEmojis, invisible = 0; for (;;) { let match, i = 0, tag; while (i < str.length && (tag = tagChars.indexOf(str[i])) === -1 && (invisible || useSystemEmojiFont || !(match = trie.search(str.slice(i))))) { i += str.codePointAt(i) < 65536 ? 1 : 2; } let rend, replacement = ''; if (i === str.length) { break; } else if (str[i] === ':') { if (!(() => { rend = str.indexOf(':', i + 1) + 1; if (!rend) return false; // no pair of ':' const lt = str.indexOf('<', i + 1); if (!(lt === -1 || lt >= rend)) return false; // tag appeared before closing ':' const shortname = str.slice(i, rend); // now got a replacee as ':shortname:' // if you want additional emoji handler, add statements below which set replacement and return true. if (shortname in customEmojis) { const filename = autoPlayGif ? customEmojis[shortname].url : customEmojis[shortname].static_url; replacement = `${shortname}`; return true; } return false; })()) rend = ++i; } else if (tag >= 0) { // <, & rend = str.indexOf('>;'[tag], i + 1) + 1; if (!rend) { break; } if (tag === 0) { if (invisible) { if (str[i + 1] === '/') { // closing tag if (!--invisible) { tagChars = tagCharsWithEmojis; } } else if (str[rend - 2] !== '/') { // opening tag invisible++; } } else { if (str.startsWith('