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.

137 lines
3.0 KiB

  1. // This code is largely borrowed from:
  2. // https://github.com/missive/emoji-mart/blob/bbd4fbe/src/utils/index.js
  3. import data from './emoji_data_light';
  4. const COLONS_REGEX = /^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/;
  5. function buildSearch(thisData) {
  6. const search = [];
  7. let addToSearch = (strings, split) => {
  8. if (!strings) {
  9. return;
  10. }
  11. (Array.isArray(strings) ? strings : [strings]).forEach((string) => {
  12. (split ? string.split(/[-|_|\s]+/) : [string]).forEach((s) => {
  13. s = s.toLowerCase();
  14. if (search.indexOf(s) === -1) {
  15. search.push(s);
  16. }
  17. });
  18. });
  19. };
  20. addToSearch(thisData.short_names, true);
  21. addToSearch(thisData.name, true);
  22. addToSearch(thisData.keywords, false);
  23. addToSearch(thisData.emoticons, false);
  24. return search;
  25. }
  26. function unifiedToNative(unified) {
  27. let unicodes = unified.split('-'),
  28. codePoints = unicodes.map((u) => `0x${u}`);
  29. return String.fromCodePoint(...codePoints);
  30. }
  31. function sanitize(emoji) {
  32. let { name, short_names, skin_tone, skin_variations, emoticons, unified, custom, imageUrl } = emoji,
  33. id = emoji.id || short_names[0],
  34. colons = `:${id}:`;
  35. if (custom) {
  36. return {
  37. id,
  38. name,
  39. colons,
  40. emoticons,
  41. custom,
  42. imageUrl,
  43. };
  44. }
  45. if (skin_tone) {
  46. colons += `:skin-tone-${skin_tone}:`;
  47. }
  48. return {
  49. id,
  50. name,
  51. colons,
  52. emoticons,
  53. unified: unified.toLowerCase(),
  54. skin: skin_tone || (skin_variations ? 1 : null),
  55. native: unifiedToNative(unified),
  56. };
  57. }
  58. function getSanitizedData(emoji) {
  59. return sanitize(getData(emoji));
  60. }
  61. function getData(emoji) {
  62. let emojiData = {};
  63. if (typeof emoji === 'string') {
  64. let matches = emoji.match(COLONS_REGEX);
  65. if (matches) {
  66. emoji = matches[1];
  67. }
  68. if (data.short_names.hasOwnProperty(emoji)) {
  69. emoji = data.short_names[emoji];
  70. }
  71. if (data.emojis.hasOwnProperty(emoji)) {
  72. emojiData = data.emojis[emoji];
  73. }
  74. } else if (emoji.custom) {
  75. emojiData = emoji;
  76. emojiData.search = buildSearch({
  77. short_names: emoji.short_names,
  78. name: emoji.name,
  79. keywords: emoji.keywords,
  80. emoticons: emoji.emoticons,
  81. });
  82. emojiData.search = emojiData.search.join(',');
  83. } else if (emoji.id) {
  84. if (data.short_names.hasOwnProperty(emoji.id)) {
  85. emoji.id = data.short_names[emoji.id];
  86. }
  87. if (data.emojis.hasOwnProperty(emoji.id)) {
  88. emojiData = data.emojis[emoji.id];
  89. }
  90. }
  91. emojiData.emoticons = emojiData.emoticons || [];
  92. emojiData.variations = emojiData.variations || [];
  93. if (emojiData.variations && emojiData.variations.length) {
  94. emojiData = JSON.parse(JSON.stringify(emojiData));
  95. emojiData.unified = emojiData.variations.shift();
  96. }
  97. return emojiData;
  98. }
  99. function intersect(a, b) {
  100. let aSet = new Set(a);
  101. let bSet = new Set(b);
  102. let intersection = new Set(
  103. [...aSet].filter(x => bSet.has(x))
  104. );
  105. return Array.from(intersection);
  106. }
  107. export { getData, getSanitizedData, intersect };