'use client' import { findRawContentStart } from '@admin/utils/editor/find-raw-content-start' import { getRawContentKind } from '@admin/utils/editor/get-raw-content-kind' import { getRawContentToken } from '@admin/utils/editor/get-raw-content-token' import { getStringAttr } from '@admin/utils/editor/get-string-attr' import { matchRawContentBlock } from '@admin/utils/editor/match-raw-content-block' import { RawContentBlockNodeView } from '@admin/utils/editor/raw-content-block-node-view' import { mergeAttributes, Node as TiptapNode } from '@tiptap/core' export const ContentEditorRawContentBlock = TiptapNode.create({ name: 'rawContentBlock', group: 'block', atom: true, selectable: true, addAttributes() { return { kind: { default: 'html' }, raw: { default: '' } } }, parseHTML() { return [ { tag: 'div[data-content-editor-raw-block]', getAttrs: (element) => { if (!(element instanceof HTMLElement)) return false return { kind: getRawContentKind(element.dataset.contentEditorRawBlock), raw: element.dataset.raw ?? '' } } } ] }, renderHTML({ HTMLAttributes, node }) { const raw = getStringAttr(node.attrs.raw) const kind = getRawContentKind(node.attrs.kind) return [ 'div', mergeAttributes(HTMLAttributes, { 'data-content-editor-raw-block': kind, 'data-raw': raw }) ] }, parseMarkdown: (token) => { const rawToken = getRawContentToken(token) return { type: 'rawContentBlock', attrs: { kind: getRawContentKind(rawToken.kind), raw: rawToken.raw ?? rawToken.text ?? '' } } }, renderMarkdown: (node) => { return getStringAttr(node.attrs?.raw) }, markdownTokenizer: { name: 'rawContentBlock', level: 'block', start: findRawContentStart, tokenize(src) { const match = matchRawContentBlock(src) if (!match) return undefined return { type: 'rawContentBlock', raw: match.raw, text: match.raw, kind: match.kind } } }, addNodeView() { return ({ getPos, node, view }) => { return new RawContentBlockNodeView({ getPos, node, view }) } } })