{"version":3,"file":"article-body-editor-1be4243b.mjs","sources":["../../../common/resources/client/text-editor/extensions/background-color.ts","../../../common/resources/client/text-editor/extensions/indent.ts","../../../common/resources/client/text-editor/extensions/embed.ts","../../../common/resources/client/text-editor/highlight/lowlight.ts","../../../common/resources/client/text-editor/extensions/info-block.ts","../../../common/resources/client/article-editor/article-body-editor.tsx"],"sourcesContent":["import {Extension} from '@tiptap/core';\nimport '@tiptap/extension-text-style';\n\nexport type ColorOptions = {\n types: string[];\n};\n\ndeclare module '@tiptap/core' {\n interface Commands {\n bgColor: {\n setBackgroundColor: (color: string) => ReturnType;\n unsetBackgroundColor: () => ReturnType;\n };\n }\n}\n\nexport const BackgroundColor = Extension.create({\n name: 'backgroundColor',\n\n addOptions() {\n return {\n types: ['textStyle'],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n backgroundColor: {\n default: null,\n parseHTML: element =>\n element.style.backgroundColor.replace(/['\"]+/g, ''),\n renderHTML: attributes => {\n if (!attributes.backgroundColor) {\n return {};\n }\n\n return {\n style: `background-color: ${attributes.backgroundColor}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setBackgroundColor:\n backgroundColor =>\n ({chain}) => {\n return chain().setMark('textStyle', {backgroundColor}).run();\n },\n unsetBackgroundColor:\n () =>\n ({chain}) => {\n return chain()\n .setMark('textStyle', {backgroundColor: null})\n .removeEmptyTextStyle()\n .run();\n },\n };\n },\n});\n","import {Command, Extension} from '@tiptap/core';\nimport {AllSelection, TextSelection, Transaction} from 'prosemirror-state';\n\ndeclare module '@tiptap/core' {\n interface Commands {\n indent: {\n indent: () => ReturnType;\n outdent: () => ReturnType;\n };\n }\n}\n\nexport const Indent = Extension.create({\n name: 'indent',\n\n addOptions: () => {\n return {\n types: ['listItem', 'paragraph'],\n minLevel: 0,\n maxLevel: 6,\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n indent: {\n renderHTML: attributes => {\n return attributes?.indent > this.options.minLevel\n ? {'data-indent': attributes.indent}\n : null;\n },\n parseHTML: element => {\n const level = Number(element.getAttribute('data-indent'));\n return level && level > this.options.minLevel ? level : null;\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n const setNodeIndentMarkup = (\n tr: Transaction,\n pos: number,\n delta: number\n ): Transaction => {\n const node = tr?.doc?.nodeAt(pos);\n\n if (node) {\n const nextLevel = (node.attrs.indent || 0) + delta;\n const {minLevel, maxLevel} = this.options;\n const indent =\n // eslint-disable-next-line no-nested-ternary\n nextLevel < minLevel\n ? minLevel\n : nextLevel > maxLevel\n ? maxLevel\n : nextLevel;\n\n if (indent !== node.attrs.indent) {\n const {indent: oldIndent, ...currentAttrs} = node.attrs;\n const nodeAttrs =\n indent > minLevel ? {...currentAttrs, indent} : currentAttrs;\n return tr.setNodeMarkup(pos, node.type, nodeAttrs, node.marks);\n }\n }\n return tr;\n };\n\n const updateIndentLevel = (tr: Transaction, delta: number): Transaction => {\n const {doc, selection} = tr;\n\n if (\n doc &&\n selection &&\n (selection instanceof TextSelection ||\n selection instanceof AllSelection)\n ) {\n const {from, to} = selection;\n doc.nodesBetween(from, to, (node, pos) => {\n if (this.options.types.includes(node.type.name)) {\n tr = setNodeIndentMarkup(tr, pos, delta);\n return false;\n }\n\n return true;\n });\n }\n\n return tr;\n };\n const applyIndent: (direction: number) => () => Command =\n direction =>\n () =>\n ({tr, state, dispatch}) => {\n const {selection} = state;\n tr = tr.setSelection(selection);\n tr = updateIndentLevel(tr, direction);\n\n if (tr.docChanged) {\n dispatch?.(tr);\n return true;\n }\n\n return false;\n };\n\n return {\n indent: applyIndent(1),\n outdent: applyIndent(-1),\n };\n },\n\n addKeyboardShortcuts() {\n return {\n Tab: ({editor}) => {\n if (editor.state.selection.to > editor.state.selection.from) {\n return this.editor.commands.indent();\n }\n return false;\n },\n 'Shift-Tab': ({editor}) => {\n if (editor.state.selection.to > editor.state.selection.from) {\n return this.editor.commands.outdent();\n }\n return false;\n },\n };\n },\n});\n","import {mergeAttributes, Node} from '@tiptap/react';\n\ndeclare module '@tiptap/core' {\n interface Commands {\n embed: {\n setEmbed: (options: {src: string}) => ReturnType;\n };\n }\n}\n\nexport const Embed = Node.create({\n name: 'embed',\n group: 'block',\n atom: true,\n\n addAttributes() {\n return {\n src: {\n default: null,\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'iframe',\n },\n ];\n },\n\n renderHTML({HTMLAttributes}) {\n return [\n 'iframe',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n ];\n },\n\n addCommands() {\n return {\n setEmbed:\n options =>\n ({commands}) => {\n return commands.insertContent({\n type: this.name,\n attrs: options,\n });\n },\n };\n },\n});\n","import {createLowlight} from 'lowlight';\n\n// load specific languages only\nimport javascript from 'highlight.js/lib/languages/javascript';\nimport typescript from 'highlight.js/lib/languages/typescript';\nimport html from 'highlight.js/lib/languages/xml';\nimport css from 'highlight.js/lib/languages/css';\nimport php from 'highlight.js/lib/languages/php';\nimport shell from 'highlight.js/lib/languages/shell';\nimport bash from 'highlight.js/lib/languages/bash';\nimport ruby from 'highlight.js/lib/languages/ruby';\nimport python from 'highlight.js/lib/languages/python';\nimport java from 'highlight.js/lib/languages/java';\nimport c from 'highlight.js/lib/languages/c';\n\n// load css\nimport './highlight-material-palenight.css';\n\nconst lowlight = createLowlight();\nlowlight.register('javascript', javascript);\nlowlight.register('typescript', typescript);\nlowlight.register('html', html);\nlowlight.register('css', css);\nlowlight.register('php', php);\nlowlight.register('shell', shell);\nlowlight.register('bash', bash);\nlowlight.register('ruby', ruby);\nlowlight.register('python', python);\nlowlight.register('java', java);\nlowlight.register('c', c);\n\nexport {lowlight};\n","import {mergeAttributes, Node} from '@tiptap/react';\n\ndeclare module '@tiptap/core' {\n interface Commands {\n important: {\n addInfo: (attributes: {\n type: 'important' | 'warning' | 'success';\n }) => ReturnType;\n };\n }\n}\n\nexport const InfoBlock = Node.create({\n name: 'be-info-block',\n group: 'block',\n content: 'inline*',\n defining: true,\n\n addAttributes() {\n return {\n type: {\n default: 'success',\n renderHTML: attrs => {\n return {class: attrs.type};\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'div',\n getAttrs: node =>\n (node as HTMLElement).classList.contains('info-block') && null,\n },\n ];\n },\n\n renderHTML({HTMLAttributes}) {\n return [\n 'div',\n mergeAttributes(HTMLAttributes, {\n class: 'info-block',\n }),\n ['div', {class: 'title'}, 'Important:'],\n ['p', 0],\n ];\n },\n\n addCommands() {\n return {\n addInfo:\n attributes =>\n ({commands}) => {\n return commands.setNode(this.name, attributes);\n },\n };\n },\n});\n","import {Editor, EditorContent, FocusPosition, useEditor} from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport {Underline} from '@tiptap/extension-underline';\nimport {Link as LinkExtension} from '@tiptap/extension-link';\nimport Image from '@tiptap/extension-image';\nimport {ReactElement, useEffect, useRef} from 'react';\nimport {Superscript} from '@tiptap/extension-superscript';\nimport {Subscript} from '@tiptap/extension-subscript';\nimport {Color} from '@tiptap/extension-color';\nimport {TextStyle} from '@tiptap/extension-text-style';\nimport {TextAlign} from '@tiptap/extension-text-align';\nimport {CodeBlockLowlight} from '@tiptap/extension-code-block-lowlight';\nimport {BackgroundColor} from '@common/text-editor/extensions/background-color';\nimport {Indent} from '@common/text-editor/extensions/indent';\nimport {Embed} from '@common/text-editor/extensions/embed';\nimport {lowlight} from '@common/text-editor/highlight/lowlight';\nimport {InfoBlock} from '@common/text-editor/extensions/info-block';\nimport {useCallbackRef} from '@common/utils/hooks/use-callback-ref';\nimport {Extension} from '@tiptap/core';\n\ninterface Props {\n initialContent?: string;\n onLoad?: (editor: Editor) => void;\n children: (content: ReactElement, editor: Editor) => ReactElement;\n minHeight?: string;\n onCtrlEnter?: () => void;\n autoFocus?: FocusPosition;\n}\nexport default function ArticleBodyEditor({\n initialContent = '',\n children,\n onLoad: _onLoad,\n onCtrlEnter,\n minHeight = 'min-h-320',\n autoFocus,\n}: Props) {\n const onLoad = useCallbackRef(_onLoad);\n const calledOnLoad = useRef(false);\n\n const extensions = [\n StarterKit.configure({\n codeBlock: false,\n }),\n Underline,\n LinkExtension,\n Image,\n Superscript,\n Subscript,\n TextStyle,\n Color,\n BackgroundColor,\n Indent,\n CodeBlockLowlight.configure({\n lowlight,\n }),\n TextAlign.configure({\n types: ['heading', 'paragraph'],\n }),\n InfoBlock,\n Embed,\n ];\n\n if (onCtrlEnter) {\n extensions.push(\n Extension.create({\n addKeyboardShortcuts: () => ({\n 'Cmd-Enter'() {\n onCtrlEnter();\n return true;\n },\n 'Ctrl-Enter'() {\n onCtrlEnter();\n return true;\n },\n }),\n }),\n );\n }\n\n const editor = useEditor({\n extensions,\n onFocus: () => {},\n autofocus: autoFocus,\n content: initialContent,\n });\n\n // destroy editor\n useEffect(() => {\n if (editor) {\n return () => editor.destroy();\n }\n }, [editor]);\n\n if (!editor) {\n return null;\n }\n\n if (editor && onLoad && !calledOnLoad.current) {\n onLoad(editor);\n calledOnLoad.current = true;\n }\n\n return children(\n ,\n editor,\n );\n}\n"],"names":["LinkExtension"],"mappings":"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"}