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.

tribute.js 2.3KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import {emojiKeys, emojiHTML, emojiString} from './emoji.js';
  2. import {uniq} from '../utils.js';
  3. function makeCollections({mentions, emoji}) {
  4. const collections = [];
  5. if (mentions) {
  6. collections.push({
  7. trigger: ':',
  8. requireLeadingSpace: true,
  9. values: (query, cb) => {
  10. const matches = [];
  11. for (const name of emojiKeys) {
  12. if (name.includes(query)) {
  13. matches.push(name);
  14. if (matches.length > 5) break;
  15. }
  16. }
  17. cb(matches);
  18. },
  19. lookup: (item) => item,
  20. selectTemplate: (item) => {
  21. if (typeof item === 'undefined') return null;
  22. return emojiString(item.original);
  23. },
  24. menuItemTemplate: (item) => {
  25. return `<div class="tribute-item">${emojiHTML(item.original)}<span>${item.original}</span></div>`;
  26. }
  27. });
  28. }
  29. if (emoji) {
  30. collections.push({
  31. values: window.config.tributeValues,
  32. requireLeadingSpace: true,
  33. menuItemTemplate: (item) => {
  34. return `
  35. <div class="tribute-item">
  36. <img src="${item.original.avatar}"/>
  37. <span class="name">${item.original.name}</span>
  38. ${item.original.fullname && item.original.fullname !== '' ? `<span class="fullname">${item.original.fullname}</span>` : ''}
  39. </div>
  40. `;
  41. }
  42. });
  43. }
  44. return collections;
  45. }
  46. export default async function attachTribute(elementOrNodeList, {mentions, emoji} = {}) {
  47. if (!window.config.requireTribute || !elementOrNodeList) return;
  48. const nodes = Array.from('length' in elementOrNodeList ? elementOrNodeList : [elementOrNodeList]);
  49. if (!nodes.length) return;
  50. const mentionNodes = nodes.filter((node) => {
  51. return mentions || node.id === 'content';
  52. });
  53. const emojiNodes = nodes.filter((node) => {
  54. return emoji || node.id === 'content' || node.classList.contains('emoji-input');
  55. });
  56. const uniqueNodes = uniq([...mentionNodes, ...emojiNodes]);
  57. if (!uniqueNodes.length) return;
  58. const {default: Tribute} = await import(/* webpackChunkName: "tribute" */'tributejs');
  59. const collections = makeCollections({
  60. mentions: mentions || mentionNodes.length > 0,
  61. emoji: emoji || emojiNodes.length > 0,
  62. });
  63. const tribute = new Tribute({collection: collections, noMatchTemplate: ''});
  64. for (const node of uniqueNodes) {
  65. tribute.attach(node);
  66. }
  67. return tribute;
  68. }