From 1756161eadfa163c75677fb7361051edcc603fe1 Mon Sep 17 00:00:00 2001 From: fantasticit Date: Tue, 5 Apr 2022 14:01:51 +0800 Subject: [PATCH] feat: mention markdown support --- packages/client/src/tiptap/extensions/mention.ts | 16 +++++++++++++++- .../html-to-prosemirror/nodes/mention.ts | 9 +++++++++ .../html-to-prosemirror/renderer.ts | 2 ++ .../markdown-to-html/index.ts | 2 ++ .../markdown/prosemirror-to-markdown/index.ts | 2 ++ .../src/tiptap/wrappers/mention-list/index.tsx | 2 +- 6 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/nodes/mention.ts diff --git a/packages/client/src/tiptap/extensions/mention.ts b/packages/client/src/tiptap/extensions/mention.ts index 6b1ab8d4..bf9b9bef 100644 --- a/packages/client/src/tiptap/extensions/mention.ts +++ b/packages/client/src/tiptap/extensions/mention.ts @@ -2,6 +2,7 @@ import BulitInMention from '@tiptap/extension-mention'; import { ReactRenderer } from '@tiptap/react'; import tippy from 'tippy.js'; import { getUsers } from 'services/user'; +import { getDatasetAttribute } from '../utils/dataset'; import { MentionList } from '../wrappers/mention-list'; const suggestion = { @@ -59,7 +60,20 @@ const suggestion = { }, }; -export const Mention = BulitInMention.configure({ +export const Mention = BulitInMention.extend({ + addAttributes() { + return { + id: { + default: '', + parseHTML: getDatasetAttribute('id'), + }, + label: { + default: '', + parseHTML: getDatasetAttribute('label'), + }, + }; + }, +}).configure({ HTMLAttributes: { class: 'mention', }, diff --git a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/nodes/mention.ts b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/nodes/mention.ts new file mode 100644 index 00000000..8fe232c4 --- /dev/null +++ b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/nodes/mention.ts @@ -0,0 +1,9 @@ +import { Node } from './node'; + +export class Mention extends Node { + type = 'mention'; + + matching() { + return this.DOMNode.nodeName === 'DIV' && this.DOMNode.classList.contains('mention'); + } +} diff --git a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/renderer.ts b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/renderer.ts index cdb1fc62..a3ba1ab9 100644 --- a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/renderer.ts +++ b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/renderer.ts @@ -5,6 +5,7 @@ import { Banner } from './nodes/banner'; import { Status } from './nodes/status'; import { DocumentReference } from './nodes/document-reference'; import { DocumentChildren } from './nodes/document-children'; +import { Mention } from './nodes/mention'; import { Mind } from './nodes/mind'; // 通用 import { CodeBlock } from './nodes/code-block'; @@ -57,6 +58,7 @@ export class Renderer { Banner, Iframe, Status, + Mention, Mind, DocumentChildren, DocumentReference, diff --git a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/index.ts b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/index.ts index 2ce8c419..c19105ef 100644 --- a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/index.ts +++ b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/index.ts @@ -18,6 +18,7 @@ const markdownCountdown = createMarkdownContainer('countdown'); const markdownDocumentReference = createMarkdownContainer('documentReference'); const markdownDocumentChildren = createMarkdownContainer('documentChildren'); const markdownIframe = createMarkdownContainer('iframe'); +const markdownMention = createMarkdownContainer('mention'); const markdownMind = createMarkdownContainer('mind'); const markdown = markdownit('commonmark') @@ -37,6 +38,7 @@ const markdown = markdownit('commonmark') .use(markdownCountdown) .use(markdownIframe) .use(markdownStatus) + .use(markdownMention) .use(markdownMind) .use(markdownDocumentReference) .use(markdownDocumentChildren); diff --git a/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts b/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts index 18597812..4dec7751 100644 --- a/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts +++ b/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts @@ -12,6 +12,7 @@ import { HardBreak } from '../../extensions/hard-break'; import { Heading } from '../../extensions/heading'; import { HorizontalRule } from '../../extensions/horizontal-rule'; import { marks } from '../../extensions/html-marks'; +import { Mention } from '../../extensions/mention'; import { Iframe } from '../../extensions/iframe'; import { Image } from '../../extensions/image'; import { Italic } from '../../extensions/italic'; @@ -134,6 +135,7 @@ const SerializerConfig = { }, [ListItem.name]: defaultMarkdownSerializer.nodes.list_item, [Mind.name]: renderCustomContainer('mind'), + [Mention.name]: renderCustomContainer('mention'), [OrderedList.name]: renderOrderedList, [Paragraph.name]: defaultMarkdownSerializer.nodes.paragraph, [Status.name]: renderCustomContainer('status'), diff --git a/packages/client/src/tiptap/wrappers/mention-list/index.tsx b/packages/client/src/tiptap/wrappers/mention-list/index.tsx index 80edcc5b..4913951e 100644 --- a/packages/client/src/tiptap/wrappers/mention-list/index.tsx +++ b/packages/client/src/tiptap/wrappers/mention-list/index.tsx @@ -17,7 +17,7 @@ export const MentionList: React.FC = forwardRef((props, ref) => { const selectItem = (index) => { const userName = props.items[index]; if (!userName) return; - props.command({ id: userName }); + props.command({ id: userName, label: userName }); }; const upHandler = () => {