The code powering m.abunchtell.com https://m.abunchtell.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

73 lines
2.2 KiB

  1. import { unicodeMapping } from './emojione_light';
  2. import Trie from 'substring-trie';
  3. const trie = new Trie(Object.keys(unicodeMapping));
  4. const assetHost = process.env.CDN_HOST || '';
  5. const emojify = (str, customEmojis = {}) => {
  6. let rtn = '';
  7. for (;;) {
  8. let match, i = 0, tag;
  9. while (i < str.length && (tag = '<&'.indexOf(str[i])) === -1 && str[i] !== ':' && !(match = trie.search(str.slice(i)))) {
  10. i += str.codePointAt(i) < 65536 ? 1 : 2;
  11. }
  12. if (i === str.length)
  13. break;
  14. else if (tag >= 0) {
  15. const tagend = str.indexOf('>;'[tag], i + 1) + 1;
  16. if (!tagend)
  17. break;
  18. rtn += str.slice(0, tagend);
  19. str = str.slice(tagend);
  20. } else if (str[i] === ':') {
  21. try {
  22. // if replacing :shortname: succeed, exit this block with "continue"
  23. const closeColon = str.indexOf(':', i + 1) + 1;
  24. if (!closeColon) throw null; // no pair of ':'
  25. const lt = str.indexOf('<', i + 1);
  26. if (!(lt === -1 || lt >= closeColon)) throw null; // tag appeared before closing ':'
  27. const shortname = str.slice(i, closeColon);
  28. if (shortname in customEmojis) {
  29. rtn += str.slice(0, i) + `<img draggable="false" class="emojione" alt="${shortname}" title="${shortname}" src="${customEmojis[shortname]}" />`;
  30. str = str.slice(closeColon);
  31. continue;
  32. }
  33. } catch (e) {}
  34. // replacing :shortname: failed
  35. rtn += str.slice(0, i + 1);
  36. str = str.slice(i + 1);
  37. } else {
  38. const [filename, shortCode] = unicodeMapping[match];
  39. rtn += str.slice(0, i) + `<img draggable="false" class="emojione" alt="${match}" title=":${shortCode}:" src="${assetHost}/emoji/${filename}.svg" />`;
  40. str = str.slice(i + match.length);
  41. }
  42. }
  43. return rtn + str;
  44. };
  45. export default emojify;
  46. export const buildCustomEmojis = customEmojis => {
  47. const emojis = [];
  48. customEmojis.forEach(emoji => {
  49. const shortcode = emoji.get('shortcode');
  50. const url = emoji.get('url');
  51. const name = shortcode.replace(':', '');
  52. emojis.push({
  53. id: name,
  54. name,
  55. short_names: [name],
  56. text: '',
  57. emoticons: [],
  58. keywords: [name],
  59. imageUrl: url,
  60. custom: true,
  61. });
  62. });
  63. return emojis;
  64. };