mentions.js (1745B)
1 import { MarkdownSerializer, MarkdownParser } from 'prosemirror-markdown'; 2 3 /** 4 * @type {NodeSpec} 5 */ 6 export const mentionNodeSpec = { 7 attrs: { 8 type: {}, 9 id: {}, 10 label: {}, 11 }, 12 13 group: 'inline', 14 inline: true, 15 selectable: false, 16 atom: true, 17 18 toDOM: node => ['span', { 19 'class': 'mention', 20 'data-mention-type': node.attrs.type, 21 'data-mention-id': node.attrs.id, 22 }, `@${node.attrs.label}`], 23 24 parseDOM: [{ 25 tag: 'span[data-mention-type][data-mention-id]', 26 27 /** 28 * @param {Element} dom 29 * @returns {{type: string, id: string, label: string}} 30 */ 31 getAttrs: dom => { 32 const type = dom.getAttribute('data-mention-type'); 33 const id = dom.getAttribute('data-mention-id'); 34 const label = dom.innerText; 35 36 return { type, id, label }; 37 }, 38 }], 39 }; 40 41 /** 42 * @param {OrderedMap} nodes 43 * @returns {OrderedMap} 44 */ 45 export function addMentionNodes(nodes) { 46 return nodes.append({ 47 mention: mentionNodeSpec, 48 }); 49 } 50 51 export function markdownSerializer() { 52 return (state, node) => { 53 const label = state.esc(node.attrs.label || ''); 54 const uri = state.esc(`mention://${node.attrs.type}/${node.attrs.id}`); 55 56 state.write(`@[${label}](${uri})`) 57 }; 58 } 59 60 export function addMentionsToMarkdownSerializer(serializer) { 61 return new MarkdownSerializer({ 62 ...serializer.nodes, 63 mention: markdownSerializer(), 64 }, serializer.marks); 65 } 66 67 export function markdownParser() { 68 return { 69 node: 'mention', 70 getAttrs: ({ mention: { type, id, label } }) => ({ type, id, label }), 71 }; 72 } 73 74 export function addMentionsToMarkdownParser(parser) { 75 return new MarkdownParser(parser.schema, parser.tokenizer, { 76 ...parser.tokens, 77 mention: markdownParser(), 78 }); 79 }