From 24b8915983de35bd80f0c027f7fe21a3c2c1ccdc Mon Sep 17 00:00:00 2001 From: Dominik Pschenitschni Date: Thu, 4 Aug 2022 22:05:41 +0200 Subject: [PATCH 01/66] wip: tiptap editor --- package.json | 27 ++ src/components/base/CodeBlock.vue | 46 +++ src/components/base/EditorToolbar.vue | 495 ++++++++++++++++++++++++++ src/components/base/TipTap.vue | 430 ++++++++++++++++++++++ src/components/input/AsyncEditor.ts | 5 +- src/components/misc/Icon.ts | 35 +- 6 files changed, 1036 insertions(+), 2 deletions(-) create mode 100644 src/components/base/CodeBlock.vue create mode 100644 src/components/base/EditorToolbar.vue create mode 100644 src/components/base/TipTap.vue diff --git a/package.json b/package.json index e48f74baa..d76e91d47 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,32 @@ "@fortawesome/free-solid-svg-icons": "6.4.2", "@fortawesome/vue-fontawesome": "3.0.3", "@github/hotkey": "2.1.1", + "@infectoone/vue-ganttastic": "2.1.2", + "@kyvg/vue3-notification": "2.6.1", + "@sentry/tracing": "7.19.0", + "@sentry/vue": "7.19.0", + "@tiptap/extension-character-count": "2.0.0-beta.202", + "@tiptap/extension-code-block-lowlight": "2.0.0-beta.202", + "@tiptap/extension-document": "2.0.0-beta.202", + "@tiptap/extension-highlight": "2.0.0-beta.202", + "@tiptap/extension-image": "2.0.0-beta.202", + "@tiptap/extension-link": "2.0.0-beta.202", + "@tiptap/extension-table": "2.0.0-beta.202", + "@tiptap/extension-table-cell": "2.0.0-beta.202", + "@tiptap/extension-table-header": "2.0.0-beta.202", + "@tiptap/extension-table-row": "2.0.0-beta.202", + "@tiptap/extension-task-item": "2.0.0-beta.202", + "@tiptap/extension-task-list": "2.0.0-beta.202", + "@tiptap/extension-typography": "2.0.0-beta.202", + "@tiptap/starter-kit": "2.0.0-beta.202", + "@tiptap/vue-3": "2.0.0-beta.202", + "@types/is-touch-device": "1.0.0", + "@types/lodash.clonedeep": "4.5.7", + "@types/sortablejs": "1.15.0", + "@vueuse/core": "9.5.0", + "@vueuse/router": "9.5.0", + "axios": "0.27.2", + "blurhash": "2.0.4", "@infectoone/vue-ganttastic": "2.2.0", "@intlify/unplugin-vue-i18n": "1.4.0", "@kyvg/vue3-notification": "3.0.2", @@ -74,6 +100,7 @@ "is-touch-device": "1.0.1", "klona": "2.0.6", "lodash.debounce": "4.0.8", + "lowlight": "2.7.0", "marked": "9.1.2", "pinia": "2.1.7", "register-service-worker": "1.7.2", diff --git a/src/components/base/CodeBlock.vue b/src/components/base/CodeBlock.vue new file mode 100644 index 000000000..59fc6a4d6 --- /dev/null +++ b/src/components/base/CodeBlock.vue @@ -0,0 +1,46 @@ + + + + + \ No newline at end of file diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue new file mode 100644 index 000000000..0fcef1004 --- /dev/null +++ b/src/components/base/EditorToolbar.vue @@ -0,0 +1,495 @@ + + + + + diff --git a/src/components/base/TipTap.vue b/src/components/base/TipTap.vue new file mode 100644 index 000000000..16fb42431 --- /dev/null +++ b/src/components/base/TipTap.vue @@ -0,0 +1,430 @@ + + + + + + + diff --git a/src/components/input/AsyncEditor.ts b/src/components/input/AsyncEditor.ts index f80015229..47ca08bdb 100644 --- a/src/components/input/AsyncEditor.ts +++ b/src/components/input/AsyncEditor.ts @@ -1,3 +1,6 @@ import {createAsyncComponent} from '@/helpers/createAsyncComponent' -export default createAsyncComponent(() => import('@/components/input/editor.vue')) \ No newline at end of file +// const Editor = createAsyncComponent(() => import('@/components/input/editor.vue')) +const TipTap = createAsyncComponent(() => import('@/components/base/TipTap.vue')) + +export default TipTap diff --git a/src/components/misc/Icon.ts b/src/components/misc/Icon.ts index b3ea6bdc3..b989b6943 100644 --- a/src/components/misc/Icon.ts +++ b/src/components/misc/Icon.ts @@ -6,6 +6,10 @@ import { faArchive, faArrowLeft, faArrowUpFromBracket, + faBold, + faItalic, + faStrikethrough, + faCode, faBars, faBell, faBolt, @@ -29,6 +33,7 @@ import { faFilter, faForward, faGripLines, + faHeader, faHistory, faImage, faKeyboard, @@ -59,14 +64,26 @@ import { faTimes, faTrashAlt, faUser, - faUsers, faX, + faUsers, + faQuoteRight, + faListUl, + faLink, + faUndo, + faRedo, + faUnlink, + faParagraph, + faTable, + faX, } from '@fortawesome/free-solid-svg-icons' import { faBellSlash, faCalendarAlt, + faCheckSquare, faClock, faComments, + faFileImage, faSave, + faSquareCheck, faStar, faSun, faTimesCircle, @@ -76,6 +93,21 @@ import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome' import type {FontAwesomeIcon as FontAwesomeIconFixedTypes} from '@/types/vue-fontawesome' +library.add(faBold) +library.add(faUndo) +library.add(faRedo) +library.add(faItalic) +library.add(faLink) +library.add(faUnlink) +library.add(faParagraph) +library.add(faSquareCheck) +library.add(faTable) +library.add(faFileImage) +library.add(faCheckSquare) +library.add(faStrikethrough) +library.add(faCode) +library.add(faQuoteRight) +library.add(faListUl) library.add(faAlignLeft) library.add(faAngleRight) library.add(faArchive) @@ -107,6 +139,7 @@ library.add(faFillDrip) library.add(faFilter) library.add(faForward) library.add(faGripLines) +library.add(faHeader) library.add(faHistory) library.add(faImage) library.add(faKeyboard) -- 2.40.1 From ad3234b19f61efa8a364b349bde1d7443b073c7d Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Jun 2023 15:34:39 +0200 Subject: [PATCH 02/66] chore(deps): update dependencies --- package.json | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index d76e91d47..b6ca35e78 100644 --- a/package.json +++ b/package.json @@ -50,37 +50,29 @@ "@fortawesome/free-solid-svg-icons": "6.4.2", "@fortawesome/vue-fontawesome": "3.0.3", "@github/hotkey": "2.1.1", - "@infectoone/vue-ganttastic": "2.1.2", - "@kyvg/vue3-notification": "2.6.1", - "@sentry/tracing": "7.19.0", - "@sentry/vue": "7.19.0", - "@tiptap/extension-character-count": "2.0.0-beta.202", - "@tiptap/extension-code-block-lowlight": "2.0.0-beta.202", - "@tiptap/extension-document": "2.0.0-beta.202", - "@tiptap/extension-highlight": "2.0.0-beta.202", - "@tiptap/extension-image": "2.0.0-beta.202", - "@tiptap/extension-link": "2.0.0-beta.202", - "@tiptap/extension-table": "2.0.0-beta.202", - "@tiptap/extension-table-cell": "2.0.0-beta.202", - "@tiptap/extension-table-header": "2.0.0-beta.202", - "@tiptap/extension-table-row": "2.0.0-beta.202", - "@tiptap/extension-task-item": "2.0.0-beta.202", - "@tiptap/extension-task-list": "2.0.0-beta.202", - "@tiptap/extension-typography": "2.0.0-beta.202", - "@tiptap/starter-kit": "2.0.0-beta.202", - "@tiptap/vue-3": "2.0.0-beta.202", - "@types/is-touch-device": "1.0.0", - "@types/lodash.clonedeep": "4.5.7", - "@types/sortablejs": "1.15.0", - "@vueuse/core": "9.5.0", - "@vueuse/router": "9.5.0", - "axios": "0.27.2", - "blurhash": "2.0.4", "@infectoone/vue-ganttastic": "2.2.0", "@intlify/unplugin-vue-i18n": "1.4.0", "@kyvg/vue3-notification": "3.0.2", "@sentry/tracing": "7.74.0", "@sentry/vue": "7.74.0", + "@tiptap/extension-character-count": "2.0.3", + "@tiptap/extension-code-block-lowlight": "2.0.3", + "@tiptap/extension-document": "2.0.3", + "@tiptap/extension-highlight": "2.0.3", + "@tiptap/extension-image": "2.0.3", + "@tiptap/extension-link": "2.0.3", + "@tiptap/extension-table": "2.0.3", + "@tiptap/extension-table-cell": "2.0.3", + "@tiptap/extension-table-header": "2.0.3", + "@tiptap/extension-table-row": "2.0.3", + "@tiptap/extension-task-item": "2.0.3", + "@tiptap/extension-task-list": "2.0.3", + "@tiptap/extension-typography": "2.0.3", + "@tiptap/starter-kit": "2.0.3", + "@tiptap/vue-3": "2.0.3", + "@types/is-touch-device": "1.0.0", + "@types/lodash.clonedeep": "4.5.7", + "@types/sortablejs": "1.15.0", "@vueuse/core": "10.5.0", "@vueuse/router": "10.5.0", "axios": "1.5.1", -- 2.40.1 From ca0d9e6bd536afeaa680a60128fa54ca110a3914 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Jun 2023 15:48:43 +0200 Subject: [PATCH 03/66] chore(editor): add horizontal line icon --- src/components/base/EditorToolbar.vue | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index 0fcef1004..6da1adb08 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -201,7 +201,9 @@ class="editor-toolbar__button" @click="editor.chain().focus().setHorizontalRule().run()" > - horizontal rule + + - + -- 2.40.1 From c58ad4778205158bf2bf9bd6b6920c599cbed583 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Jun 2023 15:48:55 +0200 Subject: [PATCH 04/66] chore(editor): use typed props definition --- src/components/base/TipTap.vue | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/base/TipTap.vue b/src/components/base/TipTap.vue index 16fb42431..0dbb74ed6 100644 --- a/src/components/base/TipTap.vue +++ b/src/components/base/TipTap.vue @@ -72,11 +72,10 @@ const CustomTableCell = TableCell.extend({ }, }) -const props = defineProps({ - modelValue: { - type: String as PropType, - default: '', - }, +const props = withDefaults(defineProps<{ + modelValue?: string, +}>(), { + modelValue: '', }) const emit = defineEmits(['update:modelValue', 'change']) -- 2.40.1 From 9c71e30efec702f5b8e06776034a96412bf3b4c8 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Jun 2023 16:04:44 +0200 Subject: [PATCH 05/66] chore(editor): add break icon --- src/components/base/EditorToolbar.vue | 4 +++- src/components/misc/Icon.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index 6da1adb08..a1e1aa68e 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -209,7 +209,9 @@ class="editor-toolbar__button" @click="editor.chain().focus().setHardBreak().run()" > - hard break + + + diff --git a/src/components/misc/Icon.ts b/src/components/misc/Icon.ts index b989b6943..20abd0182 100644 --- a/src/components/misc/Icon.ts +++ b/src/components/misc/Icon.ts @@ -73,7 +73,7 @@ import { faUnlink, faParagraph, faTable, - faX, + faX, faArrowTurnDown, } from '@fortawesome/free-solid-svg-icons' import { faBellSlash, @@ -179,6 +179,7 @@ library.add(faArrowUpFromBracket) library.add(faX) library.add(faAnglesUp) library.add(faBolt) +library.add(faArrowTurnDown) // overwriting the wrong types export default FontAwesomeIcon as unknown as FontAwesomeIconFixedTypes \ No newline at end of file -- 2.40.1 From ddcf6bf0a5b2b38b66c1cb31807b493161a749b5 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Jun 2023 16:05:22 +0200 Subject: [PATCH 06/66] fix(editor): image button icon --- src/components/base/EditorToolbar.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index a1e1aa68e..817091c57 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -394,7 +394,7 @@
- +
-- 2.40.1 From af9eb358ee7ca5fcb31cbc9b05259e8dffccc5db Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 13 Jun 2023 16:18:07 +0200 Subject: [PATCH 07/66] fix(editor): permission check for table editing --- src/components/base/EditorToolbar.vue | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index 817091c57..072bccdb5 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -264,91 +264,91 @@ addColumnBefore addColumnAfter deleteColumn addRowBefore addRowAfter deleteRow deleteTable mergeCells splitCell toggleHeaderColumn toggleHeaderRow toggleHeaderCell mergeOrSplit @@ -370,21 +370,21 @@ fixTables goToNextCell goToPreviousCell -- 2.40.1 From e760ce45e4ef2bab2e38155d5502e9d64558e96a Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 20 Jun 2023 11:33:13 +0200 Subject: [PATCH 08/66] fix(editor): checklist button icon --- src/components/base/EditorToolbar.vue | 2 +- src/components/misc/Icon.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index 072bccdb5..3b5d16f62 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -183,7 +183,7 @@ title="task list" > - + Date: Tue, 20 Jun 2023 11:40:34 +0200 Subject: [PATCH 09/66] feat(editor): make task list work --- src/components/base/TipTap.vue | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/base/TipTap.vue b/src/components/base/TipTap.vue index 0dbb74ed6..239c521dc 100644 --- a/src/components/base/TipTap.vue +++ b/src/components/base/TipTap.vue @@ -47,8 +47,8 @@ import CodeBlock from './CodeBlock.vue' // content: 'taskList', // }) -const CustomTaskItem = TaskItem.extend({ - content: 'inline*', +const CustomTaskItem = TaskItem.configure({ + nested: true, }) const CustomTableCell = TableCell.extend({ @@ -386,10 +386,15 @@ onBeforeUnmount(() => editor.value?.destroy()) ul[data-type="taskList"] { list-style: none; padding: 0; + margin-left: 0; + margin-top: 0; + + p { + margin-bottom: 0 !important; + } li { display: flex; - align-items: center; > label { flex: 0 0 auto; -- 2.40.1 From e716fd1bf9c86cf1c62eaf399ab7929c27e26ee1 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 20 Jun 2023 11:44:49 +0200 Subject: [PATCH 10/66] fix(editor): list styling --- src/components/base/TipTap.vue | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/components/base/TipTap.vue b/src/components/base/TipTap.vue index 239c521dc..ca4595c1c 100644 --- a/src/components/base/TipTap.vue +++ b/src/components/base/TipTap.vue @@ -316,8 +316,8 @@ onBeforeUnmount(() => editor.value?.destroy()) } } -/* Table-specific styling */ .ProseMirror { + /* Table-specific styling */ table { border-collapse: collapse; table-layout: fixed; @@ -371,6 +371,20 @@ onBeforeUnmount(() => editor.value?.destroy()) margin: 0; } } + + // Lists + ul { + margin-left: .5rem; + margin-top: 0 !important; + + li { + margin-top: 0; + } + + p { + margin-bottom: 0 !important; + } + } } .tableWrapper { @@ -387,11 +401,6 @@ ul[data-type="taskList"] { list-style: none; padding: 0; margin-left: 0; - margin-top: 0; - - p { - margin-bottom: 0 !important; - } li { display: flex; -- 2.40.1 From 08959fdb77d8e94f2e8c193150e68a5923ae5d69 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 20 Jun 2023 11:46:52 +0200 Subject: [PATCH 11/66] fix(editor): focus state --- src/components/base/TipTap.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/base/TipTap.vue b/src/components/base/TipTap.vue index ca4595c1c..344e47643 100644 --- a/src/components/base/TipTap.vue +++ b/src/components/base/TipTap.vue @@ -175,7 +175,7 @@ onBeforeUnmount(() => editor.value?.destroy()) border: 1px solid #ddd; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; - padding: 10px; + //padding: 10px; // font: inherit; // z-index: 0; // word-wrap: break-word; @@ -186,6 +186,8 @@ onBeforeUnmount(() => editor.value?.destroy()) /* Basic editor styles */ .ProseMirror { + padding: .5rem; + > * + * { margin-top: 0.75em; } -- 2.40.1 From 8e07d9647a02b628f8a378c1b19ef567c54ed265 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 20 Jun 2023 11:47:27 +0200 Subject: [PATCH 12/66] chore(editor): move checklist to the other lists --- src/components/base/EditorToolbar.vue | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index 3b5d16f62..558014fe0 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -138,6 +138,16 @@ + + + + +
@@ -176,16 +186,6 @@ - - - - - Date: Tue, 20 Jun 2023 12:04:05 +0200 Subject: [PATCH 13/66] feat(editor): enable table --- src/components/base/EditorToolbar.vue | 29 --------------------------- src/components/base/TipTap.vue | 16 +++++++-------- 2 files changed, 7 insertions(+), 38 deletions(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index 558014fe0..720609c9a 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -352,21 +352,6 @@ > mergeOrSplit - fixTables - - goToNextCell - - - goToPreviousCell -
diff --git a/src/components/base/TipTap.vue b/src/components/base/TipTap.vue index 344e47643..d93f2dcac 100644 --- a/src/components/base/TipTap.vue +++ b/src/components/base/TipTap.vue @@ -111,15 +111,13 @@ const editor = useEditor({ openOnClick: false, validate: (href: string) => /^https?:\/\//.test(href), }), - // Table.configure({ - // resizable: true, - // }), - // TableRow, - // TableHeader, - // // Default TableCell - // // TableCell, - // // Custom TableCell with backgroundColor attribute - // CustomTableCell, + Table.configure({ + resizable: true, + }), + TableRow, + TableHeader, + // Custom TableCell with backgroundColor attribute + CustomTableCell, // // start // Document, -- 2.40.1 From 8b60e5b2c8b35a2ba466151bd6e5fd003dbb5804 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 20 Jun 2023 12:09:01 +0200 Subject: [PATCH 14/66] fix(editor): add icons for clearing marks and nodes --- src/components/base/EditorToolbar.vue | 22 +++++++++++----------- src/components/misc/Icon.ts | 4 +++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index 720609c9a..94de3d2fa 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -150,18 +150,26 @@ +
+ + + + + +
+
- clear marks + - clear nodes +
@@ -361,14 +369,6 @@ - -
- - - - - -
@@ -457,7 +457,7 @@ function setLink() { .editor-toolbar__button { color: var(--grey-700); - // width: 30px; + min-width: 30px; height: 30px; border-radius: 3px; border: 1px solid transparent; diff --git a/src/components/misc/Icon.ts b/src/components/misc/Icon.ts index 11169dc2d..5300d07a2 100644 --- a/src/components/misc/Icon.ts +++ b/src/components/misc/Icon.ts @@ -73,7 +73,7 @@ import { faUnlink, faParagraph, faTable, - faX, faArrowTurnDown, faListCheck, + faX, faArrowTurnDown, faListCheck, faXmark, faXmarksLines, } from '@fortawesome/free-solid-svg-icons' import { faBellSlash, @@ -181,6 +181,8 @@ library.add(faAnglesUp) library.add(faBolt) library.add(faArrowTurnDown) library.add(faListCheck) +library.add(faXmark) +library.add(faXmarksLines) // overwriting the wrong types export default FontAwesomeIcon as unknown as FontAwesomeIconFixedTypes \ No newline at end of file -- 2.40.1 From 953361c480634bb06d3d9d742fe83b17bab00240 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 20 Oct 2023 17:10:55 +0200 Subject: [PATCH 15/66] chore(deps): update lockfile --- pnpm-lock.yaml | 765 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 747 insertions(+), 18 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3c54e6d2c..ac203261f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,6 +40,60 @@ dependencies: '@sentry/vue': specifier: 7.74.0 version: 7.74.0(vue@3.3.6) + '@tiptap/extension-character-count': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-code-block-lowlight': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-document': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12) + '@tiptap/extension-highlight': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12) + '@tiptap/extension-image': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12) + '@tiptap/extension-link': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-table': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-table-cell': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12) + '@tiptap/extension-table-header': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12) + '@tiptap/extension-table-row': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12) + '@tiptap/extension-task-item': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-task-list': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12) + '@tiptap/extension-typography': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12) + '@tiptap/starter-kit': + specifier: 2.0.3 + version: 2.0.3(@tiptap/pm@2.1.12) + '@tiptap/vue-3': + specifier: 2.0.3 + version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)(vue@3.3.6) + '@types/is-touch-device': + specifier: 1.0.0 + version: 1.0.0 + '@types/lodash.clonedeep': + specifier: 4.5.7 + version: 4.5.7 + '@types/sortablejs': + specifier: 1.15.0 + version: 1.15.0 '@vueuse/core': specifier: 10.5.0 version: 10.5.0(vue@3.3.6) @@ -97,6 +151,9 @@ dependencies: lodash.debounce: specifier: 4.0.8 version: 4.0.8 + lowlight: + specifier: 2.7.0 + version: 2.7.0 marked: specifier: 9.1.2 version: 9.1.2 @@ -171,9 +228,6 @@ devDependencies: '@types/flexsearch': specifier: 0.7.5 version: 0.7.5 - '@types/is-touch-device': - specifier: 1.0.1 - version: 1.0.1 '@types/lodash.debounce': specifier: 4.0.8 version: 4.0.8 @@ -186,9 +240,6 @@ devDependencies: '@types/postcss-preset-env': specifier: 7.7.0 version: 7.7.0 - '@types/sortablejs': - specifier: 1.15.4 - version: 1.15.4 '@typescript-eslint/eslint-plugin': specifier: 6.8.0 version: 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.2.2) @@ -3882,6 +3933,38 @@ packages: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true + /@popperjs/core@2.11.8: + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + dev: false + + /@remirror/core-constants@2.0.2: + resolution: {integrity: sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==} + dev: false + + /@remirror/core-helpers@3.0.0: + resolution: {integrity: sha512-tusEgQJIqg4qKj6HSBUFcyRnWnziw3neh4T9wOmsPGHFC3w9kl5KSrDb9UAgE8uX6y32FnS7vJ955mWOl3n50A==} + dependencies: + '@remirror/core-constants': 2.0.2 + '@remirror/types': 1.0.1 + '@types/object.omit': 3.0.2 + '@types/object.pick': 1.3.3 + '@types/throttle-debounce': 2.1.0 + case-anything: 2.1.13 + dash-get: 1.0.2 + deepmerge: 4.3.1 + fast-deep-equal: 3.1.3 + make-error: 1.3.6 + object.omit: 3.0.0 + object.pick: 1.3.0 + throttle-debounce: 3.0.1 + dev: false + + /@remirror/types@1.0.1: + resolution: {integrity: sha512-VlZQxwGnt1jtQ18D6JqdIF+uFZo525WEqrfp9BOc3COPpK4+AWCgdnAWL+ho6imWcoINlGjR/+3b6y5C1vBVEA==} + dependencies: + type-fest: 2.19.0 + dev: false + /@remusao/guess-url-type@1.2.1: resolution: {integrity: sha512-rbOqre2jW8STjheOsOaQHLgYBaBZ9Owbdt8NO7WvNZftJlaG3y/K9oOkl8ZUpuFBisIhmBuMEW6c+YrQl5inRA==} dev: true @@ -4113,6 +4196,362 @@ packages: defer-to-connect: 1.1.3 dev: true + /@tiptap/core@2.1.12(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-ZGc3xrBJA9KY8kln5AYTj8y+GDrKxi7u95xIl2eccrqTY5CQeRu6HRNM1yT4mAjuSaG9jmazyjGRlQuhyxCKxQ==} + peerDependencies: + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-blockquote@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-Qb3YRlCfugx9pw7VgLTb+jY37OY4aBJeZnqHzx4QThSm13edNYjasokbX0nTwL1Up4NPTcY19JUeHt6fVaVVGg==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-bold@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-AZGxIxcGU1/y6V2YEbKsq6BAibL8yQrbRm6EdcBnby41vj1WziewEKswhLGmZx5IKM2r2ldxld03KlfSIlKQZg==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-bubble-menu@2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-gAGi21EQ4wvLmT7klgariAc2Hf+cIjaNU2NWze3ut6Ku9gUo5ZLqj1t9SKHmNf4d5JG63O8GxpErqpA7lHlRtw==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + tippy.js: 6.3.7 + dev: false + + /@tiptap/extension-bullet-list@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-vtD8vWtNlmAZX8LYqt2yU9w3mU9rPCiHmbp4hDXJs2kBnI0Ju/qAyXFx6iJ3C3XyuMnMbJdDI9ee0spAvFz7cQ==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-character-count@2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-Ge4aUmgYOmQR/HLPkbQSFKEywyRu6IalHAQmH3laY6LB9qrmT90AoaiFnaVCDpphYFQ7RygnBXJMgjtJ3WpZmw==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-code-block-lowlight@2.0.3(@tiptap/core@2.1.12)(@tiptap/extension-code-block@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-thFXcFdFyHF0/dr9sqBedjj0Vt14k3m52YVc4l65+d65wRuHp4f8suu8T2ZGRJwqLCE3NIrvwQTSHhzjIqJVxQ==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/extension-code-block': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/extension-code-block': 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-code-block@2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-RXtSYCVsnk8D+K80uNZShClfZjvv1EgO42JlXLVGWQdIgaNyuOv/6I/Jdf+ZzhnpsBnHufW+6TJjwP5vJPSPHA==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-code@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-CRiRq5OTC1lFgSx6IMrECqmtb93a0ZZKujEnaRhzWliPBjLIi66va05f/P1vnV6/tHaC3yfXys6dxB5A4J8jxw==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-document@2.0.3(@tiptap/core@2.1.12): + resolution: {integrity: sha512-PsYeNQQBYIU9ayz1R11Kv/kKNPFNIV8tApJ9pxelXjzcAhkjncNUazPN/dyho60mzo+WpsmS3ceTj/gK3bCtWA==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-dropcursor@2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-0tT/q8nL4NBCYPxr9T0Brck+RQbWuczm9nV0bnxgt0IiQXoRHutfPWdS7GA65PTuVRBS/3LOco30fbjFhkfz/A==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-floating-menu@2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-uo0ydCJNg6AWwLT6cMUJYVChfvw2PY9ZfvKRhh9YJlGfM02jS4RUG/bJBts6R37f+a5FsOvAVwg8EvqPlNND1A==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + tippy.js: 6.3.7 + dev: false + + /@tiptap/extension-gapcursor@2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-zFYdZCqPgpwoB7whyuwpc8EYLYjUE5QYKb8vICvc+FraBUDM51ujYhFSgJC3rhs8EjI+8GcK8ShLbSMIn49YOQ==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-hard-break@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-nqKcAYGEOafg9D+2cy1E4gHNGuL12LerVa0eS2SQOb+PT8vSel9OTKU1RyZldsWSQJ5rq/w4uIjmLnrSR2w6Yw==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-heading@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-MoANP3POAP68Ko9YXarfDKLM/kXtscgp6m+xRagPAghRNujVY88nK1qBMZ3JdvTVN6b/ATJhp8UdrZX96TLV2w==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-highlight@2.0.3(@tiptap/core@2.1.12): + resolution: {integrity: sha512-NrtibY8cZkIjZMQuHRrKd4php+plOvAoSo8g3uVFu275I/Ixt5HqJ53R4voCXs8W8BOBRs2HS2QX8Cjh79XhtA==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-history@2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-6b7UFVkvPjq3LVoCTrYZAczt5sQrQUaoDWAieVClVZoFLfjga2Fwjcfgcie8IjdPt8YO2hG/sar/c07i9vM0Sg==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-horizontal-rule@2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-RRuoK4KxrXRrZNAjJW5rpaxjiP0FJIaqpi7nFbAua2oHXgsCsG8qbW2Y0WkbIoS8AJsvLZ3fNGsQ8gpdliuq3A==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-image@2.0.3(@tiptap/core@2.1.12): + resolution: {integrity: sha512-hS9ZJwz0md07EHsC+o4NuuJkhCZsZn7TuRz/2CvRSj2fWFIz+40CyNAHf/2J0qNugG9ommXaemetsADeEZP9ag==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-italic@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-/XYrW4ZEWyqDvnXVKbgTXItpJOp2ycswk+fJ3vuexyolO6NSs0UuYC6X4f+FbHYL5VuWqVBv7EavGa+tB6sl3A==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-link@2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-H72tXQ5rkVCkAhFaf08fbEU7EBUCK0uocsqOF+4th9sOlrhfgyJtc8Jv5EXPDpxNgG5jixSqWBo0zKXQm9s9eg==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + linkifyjs: 4.1.1 + dev: false + + /@tiptap/extension-list-item@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-Gk7hBFofAPmNQ8+uw8w5QSsZOMEGf7KQXJnx5B022YAUJTYYxO3jYVuzp34Drk9p+zNNIcXD4kc7ff5+nFOTrg==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-ordered-list@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-tF6VGl+D2avCgn9U/2YLJ8qVmV6sPE/iEzVAFZuOSe6L0Pj7SQw4K6AO640QBob/d8VrqqJFHCb6l10amJOnXA==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-paragraph@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-hoH/uWPX+KKnNAZagudlsrr4Xu57nusGekkJWBcrb5MCDE91BS+DN2xifuhwXiTHxnwOMVFjluc0bPzQbkArsw==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-strike@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-HlhrzIjYUT8oCH9nYzEL2QTTn8d1ECnVhKvzAe6x41xk31PjLMHTUy8aYjeQEkWZOWZ34tiTmslV1ce6R3Dt8g==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-table-cell@2.0.3(@tiptap/core@2.1.12): + resolution: {integrity: sha512-d0vpwQfRIOhqKJdoiOJybwWhjnug3QA4Mkgccp378moDRyOer3hPKavG1Ljgz087qHrN4WfdUlMGEvasYsWE7w==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-table-header@2.0.3(@tiptap/core@2.1.12): + resolution: {integrity: sha512-SnGl1U6usRRS6LyAjSdhaCYLF6NWbGhjVFSmiPrjb0pOzsiVeDOiUNCyUAIYaDNnjAF2pfK6+H+uHzYPqTi+/w==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-table-row@2.0.3(@tiptap/core@2.1.12): + resolution: {integrity: sha512-tyqeXmQLNSBsYyiNsnQuJMxNbz6dYt+P5W58+h10mjbt+hERA5+alQQyP06O2DggsT3Z0LPt7QRAlNmOBe7cyQ==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-table@2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-8swHqm8vRM1w9WzaAhLmY24gGoTozctz4KHKBjvFY/Ka0yXabT0+hoCCdkZLnXWi15H3pbHs2HnDBaTGL9bZTw==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-task-item@2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-13u1Q769WiSNcjFieYAMuJyWXNaY9yOdw6WFg9tQg4EZ5h6+2DaxB0qmu6I3pH+wwSn2UkCkXIirAo/k7wnzbw==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + + /@tiptap/extension-task-list@2.0.3(@tiptap/core@2.1.12): + resolution: {integrity: sha512-NdW0RtMF2L96qy+j946mTB5Av6Qn5L3vGVWFmJA6/JPXr9Uj/grItCmqUQKHfPBSFow7UqBY82ODblP+GQFgew==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-text@2.1.12(@tiptap/core@2.1.12): + resolution: {integrity: sha512-rCNUd505p/PXwU9Jgxo4ZJv4A3cIBAyAqlx/dtcY6cjztCQuXJhuQILPhjGhBTOLEEL4kW2wQtqzCmb7O8i2jg==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/extension-typography@2.0.3(@tiptap/core@2.1.12): + resolution: {integrity: sha512-5U91O2dffYOvwenWG+zT1N/pnt+RppSlocxs1KaNWFLlI2fgzDTyUyjzygIHGmskStqay2MuvmPnfVABoC+1Gw==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + dev: false + + /@tiptap/pm@2.1.12: + resolution: {integrity: sha512-Q3MXXQABG4CZBesSp82yV84uhJh/W0Gag6KPm2HRWPimSFELM09Z9/5WK9RItAYE0aLhe4Krnyiczn9AAa1tQQ==} + dependencies: + prosemirror-changeset: 2.2.1 + prosemirror-collab: 1.3.1 + prosemirror-commands: 1.5.2 + prosemirror-dropcursor: 1.8.1 + prosemirror-gapcursor: 1.3.2 + prosemirror-history: 1.3.2 + prosemirror-inputrules: 1.2.1 + prosemirror-keymap: 1.2.2 + prosemirror-markdown: 1.11.2 + prosemirror-menu: 1.2.4 + prosemirror-model: 1.19.3 + prosemirror-schema-basic: 1.2.2 + prosemirror-schema-list: 1.3.0 + prosemirror-state: 1.4.3 + prosemirror-tables: 1.3.4 + prosemirror-trailing-node: 2.0.7(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.1) + prosemirror-transform: 1.8.0 + prosemirror-view: 1.32.1 + dev: false + + /@tiptap/starter-kit@2.0.3(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-t4WG4w93zTpL2VxhVyJJvl3kdLF001ZrhpOuEiZqEMBMUMbM56Uiigv1CnUQpTFrjDAh3IM8hkqzAh20TYw2iQ==} + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/extension-blockquote': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-bold': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-bullet-list': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-code': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-code-block': 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-document': 2.0.3(@tiptap/core@2.1.12) + '@tiptap/extension-dropcursor': 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-gapcursor': 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-hard-break': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-heading': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-history': 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-horizontal-rule': 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-italic': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-list-item': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-ordered-list': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-paragraph': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-strike': 2.1.12(@tiptap/core@2.1.12) + '@tiptap/extension-text': 2.1.12(@tiptap/core@2.1.12) + transitivePeerDependencies: + - '@tiptap/pm' + dev: false + + /@tiptap/vue-3@2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)(vue@3.3.6): + resolution: {integrity: sha512-2CtNUzt+e7sgvIjxPOyBwoiRcuCHNeJzW+XGxNK2uCWlAKp/Yw3boJ51d51UuIbj9RitGHJ5GpCdLJoL7SDiQA==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + vue: ^3.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/extension-bubble-menu': 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/extension-floating-menu': 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + vue: 3.3.6(typescript@5.2.2) + dev: false + /@tootallnate/once@2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} @@ -4190,9 +4629,15 @@ packages: resolution: {integrity: sha512-o0J30wqycjF5miWDKYKKzzOU1ZTLuA42HZ4HE7/zqTOc/jTLdQ5NhYWvsRQo45Nfi1KHoRdNhteSI4BAxTF1Pg==} dev: true - /@types/is-touch-device@1.0.1: - resolution: {integrity: sha512-Hvjx/zLnZF9AVHNcFZEluntFA59OWUYbmrkS7oDWoHnibO86n0nTrCI7wBGR0u8Y/E8XIj3nuUrK8hNQmqiZ7Q==} - dev: true + /@types/hast@2.3.7: + resolution: {integrity: sha512-EVLigw5zInURhzfXUM65eixfadfsHKomGKUakToXo84t8gGIJuTcD2xooM2See7GyQ7DRtYjhCHnSUQez8JaLw==} + dependencies: + '@types/unist': 2.0.9 + dev: false + + /@types/is-touch-device@1.0.0: + resolution: {integrity: sha512-/rErV0NuroAR9EZF1xK0TrihQ/7BbVckGfSr/suq/E4tJQLr4TrADR0qAUpDs/hxtl1NiP0V/ho+fSA/5EIO9Q==} + dev: false /@types/json-schema@7.0.12: resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} @@ -4208,6 +4653,12 @@ packages: resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==} dev: true + /@types/lodash.clonedeep@4.5.7: + resolution: {integrity: sha512-ccNqkPptFIXrpVqUECi60/DFxjNKsfoQxSQsgcBJCX/fuX1wgyQieojkcWH/KpE3xzLoWN/2k+ZeGqIN3paSvw==} + dependencies: + '@types/lodash': 4.14.185 + dev: false + /@types/lodash.debounce@4.0.8: resolution: {integrity: sha512-REumepIJjQFSOaBUoj81U5ZzF9YIhovzE2Lm6ejUbycmwx597k2ivG1cVfPtAj4eVuSbGoZDkJR0sRIahsE6/Q==} dependencies: @@ -4216,7 +4667,6 @@ packages: /@types/lodash@4.14.185: resolution: {integrity: sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==} - dev: true /@types/markdown-it@12.2.3: resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} @@ -4253,6 +4703,14 @@ packages: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true + /@types/object.omit@3.0.2: + resolution: {integrity: sha512-BxWU36cMP+FKD3OLFluQaj2cBev2sx2LJaHELuphHwnleq+xnEhTmuYYYx4pOT/1U/ZoR6B+RdvxWh2FD6lGGA==} + dev: false + + /@types/object.pick@1.3.3: + resolution: {integrity: sha512-qZqHmdGEALeSATMB1djT1S5szv6Wtpb7DKpHrt2XG4iyKlV7C2Xk8GmDXr1KXakOqUfX6ohw7ceruYt4NVmB1Q==} + dev: false + /@types/postcss-preset-env@7.7.0: resolution: {integrity: sha512-biD8MwSiZo1Nztn1cIBPMcKNKzgFyU05AB96HIF9y3G4f9vdx2O60DHCSpWXChTp6mOEGu15fqIw2DetVVjghw==} dependencies: @@ -4284,19 +4742,27 @@ packages: resolution: {integrity: sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==} dev: true - /@types/sortablejs@1.15.4: - resolution: {integrity: sha512-7oL7CcPSfoyoNx3Ba1+79ykJzpEKVhHUyfAiN5eT/FoeDXOR3eBDLXf9ndDNuxaExmjpI+zVi2dMMuaoXUOzNA==} - dev: true + /@types/sortablejs@1.15.0: + resolution: {integrity: sha512-qrhtM7M41EhH4tZQTNw2/RJkxllBx3reiJpTbgWCM2Dx0U1sZ6LwKp9lfNln9uqE26ZMKUaPEYaD4rzvOWYtZw==} + dev: false /@types/tern@0.23.4: resolution: {integrity: sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==} dependencies: '@types/estree': 1.0.0 + /@types/throttle-debounce@2.1.0: + resolution: {integrity: sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==} + dev: false + /@types/trusted-types@2.0.2: resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==} dev: true + /@types/unist@2.0.9: + resolution: {integrity: sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ==} + dev: false + /@types/web-bluetooth@0.0.16: resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} dev: false @@ -5467,6 +5933,11 @@ packages: - utf-8-validate dev: true + /case-anything@2.1.13: + resolution: {integrity: sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==} + engines: {node: '>=12.13'} + dev: false + /caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: true @@ -5777,7 +6248,6 @@ packages: /crelt@1.0.5: resolution: {integrity: sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==} - dev: true /cross-fetch@3.1.5: resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} @@ -5968,6 +6438,10 @@ packages: yauzl: 2.10.0 dev: true + /dash-get@1.0.2: + resolution: {integrity: sha512-4FbVrHDwfOASx7uQVxeiCTo7ggSdYZbqs8lH+WU6ViypPlDbe9y6IP5VVUDQBv9DcnyaiPT5XT0UWHgJ64zLeQ==} + dev: false + /dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} engines: {node: '>=0.10'} @@ -6086,6 +6560,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: false + /defaults@1.0.3: resolution: {integrity: sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==} dependencies: @@ -6307,6 +6786,11 @@ packages: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} dev: true + /entities@3.0.1: + resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} + engines: {node: '>=0.12'} + dev: false + /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -6435,7 +6919,6 @@ packages: /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - dev: true /escodegen@2.0.0: resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} @@ -6697,6 +7180,12 @@ packages: dependencies: reusify: 1.0.4 + /fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + dependencies: + format: 0.2.2 + dev: false + /fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} dependencies: @@ -6852,6 +7341,11 @@ packages: combined-stream: 1.0.8 mime-types: 2.1.35 + /format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + dev: false + /formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -7156,6 +7650,11 @@ packages: tslib: 2.3.1 dev: true + /highlight.js@11.6.0: + resolution: {integrity: sha512-ig1eqDzJaB0pqEvlPVIpSSyMaO92bH1N2rJpLMN/nX396wTpDA4Eq0uK+7I/2XG17pFaaKE0kjV/XPeGt7Evjw==} + engines: {node: '>=12.0.0'} + dev: false + /highlight.js@11.9.0: resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==} engines: {node: '>=12.0.0'} @@ -7441,6 +7940,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + dependencies: + is-plain-object: 2.0.4 + dev: false + /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -7522,6 +8028,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: false + /is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} dev: true @@ -7596,6 +8109,11 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true + /isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: false + /isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} dev: true @@ -7853,6 +8371,16 @@ packages: uc.micro: 1.0.6 dev: true + /linkify-it@4.0.1: + resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} + dependencies: + uc.micro: 1.0.6 + dev: false + + /linkifyjs@4.1.1: + resolution: {integrity: sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA==} + dev: false + /listr2@3.14.0(enquirer@2.3.6): resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} engines: {node: '>=10.0.0'} @@ -7956,6 +8484,14 @@ packages: engines: {node: '>=8'} dev: true + /lowlight@2.7.0: + resolution: {integrity: sha512-RRdrHalFfjpxL91ITTX7KhJYH3QmX5bW9Uie2D2E5GPIR3XBYDYhScBjE291ewFZkStz/k2PN9KC+8deNLiI3Q==} + dependencies: + '@types/hast': 2.3.7 + fault: 2.0.1 + highlight.js: 11.6.0 + dev: false + /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: @@ -7993,6 +8529,10 @@ packages: semver: 6.3.1 dev: true + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: false + /map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -8041,6 +8581,17 @@ packages: uc.micro: 1.0.6 dev: true + /markdown-it@13.0.2: + resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==} + hasBin: true + dependencies: + argparse: 2.0.1 + entities: 3.0.1 + linkify-it: 4.0.1 + mdurl: 1.0.1 + uc.micro: 1.0.6 + dev: false + /marked@4.3.0: resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} engines: {node: '>= 12'} @@ -8063,7 +8614,6 @@ packages: /mdurl@1.0.1: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} - dev: true /meow@7.1.1: resolution: {integrity: sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==} @@ -8330,6 +8880,20 @@ packages: object-keys: 1.1.1 dev: true + /object.omit@3.0.0: + resolution: {integrity: sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-extendable: 1.0.1 + dev: false + + /object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: false + /on-finished@2.3.0: resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} engines: {node: '>= 0.8'} @@ -8397,6 +8961,10 @@ packages: wcwidth: 1.0.1 dev: true + /orderedmap@2.1.1: + resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + dev: false + /os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -9044,6 +9612,149 @@ packages: engines: {node: '>=0.4.0'} dev: true + /prosemirror-changeset@2.2.1: + resolution: {integrity: sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==} + dependencies: + prosemirror-transform: 1.8.0 + dev: false + + /prosemirror-collab@1.3.1: + resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==} + dependencies: + prosemirror-state: 1.4.3 + dev: false + + /prosemirror-commands@1.5.2: + resolution: {integrity: sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==} + dependencies: + prosemirror-model: 1.19.3 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 + dev: false + + /prosemirror-dropcursor@1.8.1: + resolution: {integrity: sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==} + dependencies: + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 + prosemirror-view: 1.32.1 + dev: false + + /prosemirror-gapcursor@1.3.2: + resolution: {integrity: sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==} + dependencies: + prosemirror-keymap: 1.2.2 + prosemirror-model: 1.19.3 + prosemirror-state: 1.4.3 + prosemirror-view: 1.32.1 + dev: false + + /prosemirror-history@1.3.2: + resolution: {integrity: sha512-/zm0XoU/N/+u7i5zepjmZAEnpvjDtzoPWW6VmKptcAnPadN/SStsBjMImdCEbb3seiNTpveziPTIrXQbHLtU1g==} + dependencies: + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 + prosemirror-view: 1.32.1 + rope-sequence: 1.3.4 + dev: false + + /prosemirror-inputrules@1.2.1: + resolution: {integrity: sha512-3LrWJX1+ULRh5SZvbIQlwZafOXqp1XuV21MGBu/i5xsztd+9VD15x6OtN6mdqSFI7/8Y77gYUbQ6vwwJ4mr6QQ==} + dependencies: + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 + dev: false + + /prosemirror-keymap@1.2.2: + resolution: {integrity: sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==} + dependencies: + prosemirror-state: 1.4.3 + w3c-keyname: 2.2.6 + dev: false + + /prosemirror-markdown@1.11.2: + resolution: {integrity: sha512-Eu5g4WPiCdqDTGhdSsG9N6ZjACQRYrsAkrF9KYfdMaCmjIApH75aVncsWYOJvEk2i1B3i8jZppv3J/tnuHGiUQ==} + dependencies: + markdown-it: 13.0.2 + prosemirror-model: 1.19.3 + dev: false + + /prosemirror-menu@1.2.4: + resolution: {integrity: sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==} + dependencies: + crelt: 1.0.5 + prosemirror-commands: 1.5.2 + prosemirror-history: 1.3.2 + prosemirror-state: 1.4.3 + dev: false + + /prosemirror-model@1.19.3: + resolution: {integrity: sha512-tgSnwN7BS7/UM0sSARcW+IQryx2vODKX4MI7xpqY2X+iaepJdKBPc7I4aACIsDV/LTaTjt12Z56MhDr9LsyuZQ==} + dependencies: + orderedmap: 2.1.1 + dev: false + + /prosemirror-schema-basic@1.2.2: + resolution: {integrity: sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==} + dependencies: + prosemirror-model: 1.19.3 + dev: false + + /prosemirror-schema-list@1.3.0: + resolution: {integrity: sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==} + dependencies: + prosemirror-model: 1.19.3 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 + dev: false + + /prosemirror-state@1.4.3: + resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==} + dependencies: + prosemirror-model: 1.19.3 + prosemirror-transform: 1.8.0 + prosemirror-view: 1.32.1 + dev: false + + /prosemirror-tables@1.3.4: + resolution: {integrity: sha512-z6uLSQ1BLC3rgbGwZmpfb+xkdvD7W/UOsURDfognZFYaTtc0gsk7u/t71Yijp2eLflVpffMk6X0u0+u+MMDvIw==} + dependencies: + prosemirror-keymap: 1.2.2 + prosemirror-model: 1.19.3 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 + prosemirror-view: 1.32.1 + dev: false + + /prosemirror-trailing-node@2.0.7(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.1): + resolution: {integrity: sha512-8zcZORYj/8WEwsGo6yVCRXFMOfBo0Ub3hCUvmoWIZYfMP26WqENU0mpEP27w7mt8buZWuGrydBewr0tOArPb1Q==} + peerDependencies: + prosemirror-model: ^1.19.0 + prosemirror-state: ^1.4.2 + prosemirror-view: ^1.31.2 + dependencies: + '@remirror/core-constants': 2.0.2 + '@remirror/core-helpers': 3.0.0 + escape-string-regexp: 4.0.0 + prosemirror-model: 1.19.3 + prosemirror-state: 1.4.3 + prosemirror-view: 1.32.1 + dev: false + + /prosemirror-transform@1.8.0: + resolution: {integrity: sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==} + dependencies: + prosemirror-model: 1.19.3 + dev: false + + /prosemirror-view@1.32.1: + resolution: {integrity: sha512-9SnB4HBgRczzTyIMZLPE1iszegL04hNfUyS8uPtP1RPxNM2NTCiIs8KwNsJU4nbZO9rxJTwVTv7Jm3zU4CR78A==} + dependencies: + prosemirror-model: 1.19.3 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 + dev: false + /proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} dev: true @@ -9367,6 +10078,10 @@ packages: optionalDependencies: fsevents: 2.3.2 + /rope-sequence@1.3.4: + resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + dev: false + /run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -9881,6 +10596,11 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true + /throttle-debounce@3.0.1: + resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} + engines: {node: '>=10'} + dev: false + /throttleit@1.0.0: resolution: {integrity: sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==} dev: true @@ -9903,6 +10623,12 @@ packages: engines: {node: '>=14.0.0'} dev: true + /tippy.js@6.3.7: + resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} + dependencies: + '@popperjs/core': 2.11.8 + dev: false + /tldts-core@5.7.104: resolution: {integrity: sha512-8vhSgc2nzPNT0J7XyCqcOtQ6+ySBn+gsPmj5h95YytIZ7L2Xl40paUmj0T6Uko42HegHGQxXieunHIQuABWSmQ==} dev: true @@ -10062,6 +10788,11 @@ packages: engines: {node: '>=8'} dev: true + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: false + /typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} dependencies: @@ -10079,7 +10810,6 @@ packages: /uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} - dev: true /ufo@1.3.1: resolution: {integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==} @@ -10594,7 +11324,6 @@ packages: /w3c-keyname@2.2.6: resolution: {integrity: sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==} - dev: true /w3c-xmlserializer@4.0.0: resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} -- 2.40.1 From 05bf7ccf0b90a6ab721c03ee5d69990a4a8c0e07 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 20 Oct 2023 22:43:10 +0200 Subject: [PATCH 16/66] feat(editor): image upload --- src/components/base/EditorToolbar.vue | 50 ++++++++++++++----- src/components/base/TipTap.vue | 38 ++++++++------ src/components/tasks/partials/description.vue | 44 ++++++++++------ 3 files changed, 90 insertions(+), 42 deletions(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index 94de3d2fa..5b9436c87 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -151,7 +151,7 @@
- + @@ -369,38 +369,64 @@
+ -- 2.40.1 From 671c658868cf2509f69e359ec5d8c33907f79212 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 20 Oct 2023 22:52:21 +0200 Subject: [PATCH 17/66] fix(editor): actually populate loaded data into the editor --- src/components/base/TipTap.vue | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/base/TipTap.vue b/src/components/base/TipTap.vue index bf7fd79a9..a98045b0b 100644 --- a/src/components/base/TipTap.vue +++ b/src/components/base/TipTap.vue @@ -6,7 +6,10 @@ :upload-callback="uploadCallback" @image-added="bubbleChanges" /> - + @@ -79,10 +82,10 @@ const CustomTableCell = TableCell.extend({ }) const { - modelValue = '', + modelValue, uploadCallback, } = defineProps<{ - modelValue?: string, + modelValue: string, uploadCallback?: UploadCallback, }>() @@ -92,12 +95,17 @@ const inputHTML = ref('') watch( () => modelValue, () => { + if (modelValue === '') { + return + } + if (!modelValue.startsWith(TIPTAP_TEXT_VALUE_PREFIX)) { // convert Markdown to HTML - return TIPTAP_TEXT_VALUE_PREFIX + marked.parse(modelValue) + inputHTML.value = TIPTAP_TEXT_VALUE_PREFIX + marked.parse(modelValue) + return } - return modelValue.replace(tiptapRegex, '') + inputHTML.value = modelValue.replace(tiptapRegex, '') }, { immediate: true }, ) -- 2.40.1 From 4f3efe4454beaa95c17ee4652051091b1776f3f1 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 20 Oct 2023 23:03:38 +0200 Subject: [PATCH 18/66] feat(editor): resolve and load attachment images from content --- src/components/base/TipTap.vue | 47 ++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/components/base/TipTap.vue b/src/components/base/TipTap.vue index a98045b0b..9b4ef2333 100644 --- a/src/components/base/TipTap.vue +++ b/src/components/base/TipTap.vue @@ -4,7 +4,7 @@ v-if="editor" :editor="editor" :upload-callback="uploadCallback" - @image-added="bubbleChanges" + @image-added="onImageAdded" /> diff --git a/src/components/base/TipTap.vue b/src/components/base/TipTap.vue index 9b4ef2333..9224cbac9 100644 --- a/src/components/base/TipTap.vue +++ b/src/components/base/TipTap.vue @@ -1,14 +1,14 @@ @@ -102,7 +102,7 @@ watch( if (modelValue === '') { return } - + if (!modelValue.startsWith(TIPTAP_TEXT_VALUE_PREFIX)) { // convert Markdown to HTML inputHTML.value = TIPTAP_TEXT_VALUE_PREFIX + marked.parse(modelValue) @@ -113,7 +113,7 @@ watch( inputHTML.value = modelValue.replace(tiptapRegex, '') nextTick(() => loadImages()) }, - { immediate: true }, + {immediate: true}, ) function onImageAdded() { @@ -123,6 +123,7 @@ function onImageAdded() { type CacheKey = `${ITask['id']}-${IAttachment['id']}` const loadedAttachments = ref<{ [key: CacheKey]: string }>({}) + function loadImages() { const attachmentImage = document.querySelectorAll('.tiptap__editor img') const attachmentService = new AttachmentService() @@ -246,7 +247,7 @@ onBeforeUnmount(() => editor.value?.destroy()) /* Basic editor styles */ .ProseMirror { padding: .5rem; - + > * + * { margin-top: 0.75em; } @@ -277,7 +278,7 @@ onBeforeUnmount(() => editor.value?.destroy()) pre { background: #0d0d0d; color: #fff; - font-family: "JetBrainsMono", monospace; + font-family: 'JetBrainsMono', monospace; padding: 0.75rem 1rem; border-radius: 0.5rem; @@ -292,7 +293,7 @@ onBeforeUnmount(() => editor.value?.destroy()) pre { background: #0d0d0d; color: #fff; - font-family: "JetBrainsMono", monospace; + font-family: 'JetBrainsMono', monospace; padding: 0.75rem 1rem; border-radius: 0.5rem; @@ -409,7 +410,7 @@ onBeforeUnmount(() => editor.value?.destroy()) .selectedCell:after { z-index: 2; position: absolute; - content: ""; + content: ''; left: 0; right: 0; top: 0; @@ -432,16 +433,16 @@ onBeforeUnmount(() => editor.value?.destroy()) margin: 0; } } - + // Lists ul { margin-left: .5rem; margin-top: 0 !important; - + li { margin-top: 0; } - + p { margin-bottom: 0 !important; } @@ -458,7 +459,7 @@ onBeforeUnmount(() => editor.value?.destroy()) } // tasklist -ul[data-type="taskList"] { +ul[data-type='taskList'] { list-style: none; padding: 0; margin-left: 0; @@ -477,7 +478,7 @@ ul[data-type="taskList"] { } } - input[type="checkbox"] { + input[type='checkbox'] { cursor: pointer; } } -- 2.40.1 From c84bcfddba04c841169e4c5cdce2a80147343af2 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 21 Oct 2023 11:10:43 +0200 Subject: [PATCH 20/66] feat(editor): add proper description for all buttons --- src/components/base/EditorToolbar.vue | 45 +++++++++++++++++---------- src/i18n/lang/en.json | 19 ++++++++++- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/components/base/EditorToolbar.vue b/src/components/base/EditorToolbar.vue index a7dd78d74..88a0485e5 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/base/EditorToolbar.vue @@ -256,7 +256,7 @@ -
+
- insertTable + {{ $t('input.editor.table.insert') }} - addColumnBefore + {{ $t('input.editor.table.addColumnBefore') }} - addColumnAfter + {{ $t('input.editor.table.addColumnAfter') }} - deleteColumn + {{ $t('input.editor.table.deleteColumn') }} - addRowBefore + {{ $t('input.editor.table.addRowBefore') }} - addRowAfter + {{ $t('input.editor.table.addRowAfter') }} - deleteRow + {{ $t('input.editor.table.deleteRow') }} - deleteTable + {{ $t('input.editor.table.deleteTable') }} - mergeCells + {{ $t('input.editor.table.mergeCells') }} - splitCell + {{ $t('input.editor.table.splitCell') }} - toggleHeaderColumn + {{ $t('input.editor.table.toggleHeaderColumn') }} - toggleHeaderRow + {{ $t('input.editor.table.toggleHeaderRow') }} - toggleHeaderCell + {{ $t('input.editor.table.toggleHeaderCell') }} - mergeOrSplit + {{ $t('input.editor.table.mergeOrSplit') }} - fixTables + {{ $t('input.editor.table.fixTables') }}
@@ -499,4 +499,17 @@ function setLink() { font-weight: bold; vertical-align: top; } + +.editor-toolbar__table-buttons { + margin-top: .5rem; + + > .editor-toolbar__button { + margin-right: .5rem; + margin-bottom: .5rem; + padding: 0 .25rem; + border: 1px solid var(--grey-400); + font-size: .75rem; + height: 1.5rem; + } +} diff --git a/src/i18n/lang/en.json b/src/i18n/lang/en.json index ede8f0088..e15670dd1 100644 --- a/src/i18n/lang/en.json +++ b/src/i18n/lang/en.json @@ -531,7 +531,24 @@ "table": "Table", "horizontalRule": "Horizontal Rule", "sideBySide": "Side By Side", - "guide": "Guide" + "guide": "Guide", + "table": { + "insert": "Insert table", + "addColumnBefore": "Add column before", + "addColumnAfter": "Add column after", + "deleteColumn": "Delete column", + "addRowBefore": "Add row before", + "addRowAfter": "Add row after", + "deleteRow": "Delete row", + "deleteTable": "Delete table", + "mergeCells": "Merge cells", + "splitCell": "Split cell", + "toggleHeaderColumn": "Toggle header column", + "toggleHeaderRow": "Toggle header row", + "toggleHeaderCell": "Toggle header cell", + "mergeOrSplit": "Merge or split", + "fixTables": "Fix tables" + } }, "multiselect": { "createPlaceholder": "Create new", -- 2.40.1 From 5297208d92df271a437721eddfc04964596b0ae5 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 21 Oct 2023 11:15:07 +0200 Subject: [PATCH 21/66] feat(editor): move all editor related components into one folder --- src/components/input/AsyncEditor.ts | 2 +- src/components/{base => input/editor}/CodeBlock.vue | 0 src/components/{base => input/editor}/EditorToolbar.vue | 3 +-- src/components/{base => input/editor}/TipTap.vue | 2 +- src/components/input/editor/types.ts | 1 + 5 files changed, 4 insertions(+), 4 deletions(-) rename src/components/{base => input/editor}/CodeBlock.vue (100%) rename src/components/{base => input/editor}/EditorToolbar.vue (99%) rename src/components/{base => input/editor}/TipTap.vue (99%) create mode 100644 src/components/input/editor/types.ts diff --git a/src/components/input/AsyncEditor.ts b/src/components/input/AsyncEditor.ts index 47ca08bdb..ca7814407 100644 --- a/src/components/input/AsyncEditor.ts +++ b/src/components/input/AsyncEditor.ts @@ -1,6 +1,6 @@ import {createAsyncComponent} from '@/helpers/createAsyncComponent' // const Editor = createAsyncComponent(() => import('@/components/input/editor.vue')) -const TipTap = createAsyncComponent(() => import('@/components/base/TipTap.vue')) +const TipTap = createAsyncComponent(() => import('@/components/input/editor/TipTap.vue')) export default TipTap diff --git a/src/components/base/CodeBlock.vue b/src/components/input/editor/CodeBlock.vue similarity index 100% rename from src/components/base/CodeBlock.vue rename to src/components/input/editor/CodeBlock.vue diff --git a/src/components/base/EditorToolbar.vue b/src/components/input/editor/EditorToolbar.vue similarity index 99% rename from src/components/base/EditorToolbar.vue rename to src/components/input/editor/EditorToolbar.vue index 88a0485e5..aac57a429 100644 --- a/src/components/base/EditorToolbar.vue +++ b/src/components/input/editor/EditorToolbar.vue @@ -376,11 +376,10 @@ + + \ No newline at end of file diff --git a/src/components/input/editor/commands.js b/src/components/input/editor/commands.js new file mode 100644 index 000000000..a16f097c9 --- /dev/null +++ b/src/components/input/editor/commands.js @@ -0,0 +1,26 @@ +import { Extension } from '@tiptap/core' +import Suggestion from '@tiptap/suggestion' + +export default Extension.create({ + name: 'commands', + + addOptions() { + return { + suggestion: { + char: '/', + command: ({ editor, range, props }) => { + props.command({ editor, range }) + }, + }, + } + }, + + addProseMirrorPlugins() { + return [ + Suggestion({ + editor: this.editor, + ...this.options.suggestion, + }), + ] + }, +}) \ No newline at end of file diff --git a/src/components/input/editor/suggestion.js b/src/components/input/editor/suggestion.js new file mode 100644 index 000000000..58c501023 --- /dev/null +++ b/src/components/input/editor/suggestion.js @@ -0,0 +1,113 @@ +import { VueRenderer } from '@tiptap/vue-3' +import tippy from 'tippy.js' + +import CommandsList from './CommandsList.vue' + +export default { + items: ({ query }) => { + return [ + { + title: 'H1', + command: ({ editor, range }) => { + editor + .chain() + .focus() + .deleteRange(range) + .setNode('heading', { level: 1 }) + .run() + }, + }, + { + title: 'H2', + command: ({ editor, range }) => { + editor + .chain() + .focus() + .deleteRange(range) + .setNode('heading', { level: 2 }) + .run() + }, + }, + { + title: 'bold', + command: ({ editor, range }) => { + editor + .chain() + .focus() + .deleteRange(range) + .setMark('bold') + .run() + }, + }, + { + title: 'italic', + command: ({ editor, range }) => { + editor + .chain() + .focus() + .deleteRange(range) + .setMark('italic') + .run() + }, + }, + ].filter(item => item.title.toLowerCase().startsWith(query.toLowerCase())).slice(0, 10) + }, + + render: () => { + let component + let popup + + return { + onStart: props => { + component = new VueRenderer(CommandsList, { + // using vue 2: + // parent: this, + // propsData: props, + props, + editor: props.editor, + }) + + if (!props.clientRect) { + return + } + + popup = tippy('body', { + getReferenceClientRect: props.clientRect, + appendTo: () => document.body, + content: component.element, + showOnCreate: true, + interactive: true, + trigger: 'manual', + placement: 'bottom-start', + }) + }, + + onUpdate(props) { + component.updateProps(props) + + if (!props.clientRect) { + return + } + + popup[0].setProps({ + getReferenceClientRect: props.clientRect, + }) + }, + + onKeyDown(props) { + if (props.event.key === 'Escape') { + popup[0].hide() + + return true + } + + return component.ref?.onKeyDown(props) + }, + + onExit() { + popup[0].destroy() + component.destroy() + }, + } + }, +} \ No newline at end of file -- 2.40.1 From 3bf806f00c4bfe7bd904460c2e1c760cbfb9dd38 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 21 Oct 2023 11:46:02 +0200 Subject: [PATCH 23/66] fix(editor): add missing dependencies for commands --- package.json | 3 +++ pnpm-lock.yaml | 19 +++++++++++++++++++ src/components/input/editor/TipTap.vue | 7 +++++++ .../input/editor/{commands.js => commands.ts} | 2 ++ .../editor/{suggestion.js => suggestion.ts} | 0 5 files changed, 31 insertions(+) rename src/components/input/editor/{commands.js => commands.ts} (74%) rename src/components/input/editor/{suggestion.js => suggestion.ts} (100%) diff --git a/package.json b/package.json index b6ca35e78..dae5d2562 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "@kyvg/vue3-notification": "3.0.2", "@sentry/tracing": "7.74.0", "@sentry/vue": "7.74.0", + "@tiptap/core": "^2.1.12", "@tiptap/extension-character-count": "2.0.3", "@tiptap/extension-code-block-lowlight": "2.0.3", "@tiptap/extension-document": "2.0.3", @@ -69,6 +70,7 @@ "@tiptap/extension-task-list": "2.0.3", "@tiptap/extension-typography": "2.0.3", "@tiptap/starter-kit": "2.0.3", + "@tiptap/suggestion": "^2.1.12", "@tiptap/vue-3": "2.0.3", "@types/is-touch-device": "1.0.0", "@types/lodash.clonedeep": "4.5.7", @@ -98,6 +100,7 @@ "register-service-worker": "1.7.2", "snake-case": "3.0.4", "sortablejs": "1.15.0", + "tippy.js": "^6.3.7", "ufo": "1.3.1", "vue": "3.3.6", "vue-advanced-cropper": "2.8.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac203261f..4304b5f39 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,6 +40,9 @@ dependencies: '@sentry/vue': specifier: 7.74.0 version: 7.74.0(vue@3.3.6) + '@tiptap/core': + specifier: ^2.1.12 + version: 2.1.12(@tiptap/pm@2.1.12) '@tiptap/extension-character-count': specifier: 2.0.3 version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) @@ -82,6 +85,9 @@ dependencies: '@tiptap/starter-kit': specifier: 2.0.3 version: 2.0.3(@tiptap/pm@2.1.12) + '@tiptap/suggestion': + specifier: ^2.1.12 + version: 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12) '@tiptap/vue-3': specifier: 2.0.3 version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)(vue@3.3.6) @@ -169,6 +175,9 @@ dependencies: sortablejs: specifier: 1.15.0 version: 1.15.0 + tippy.js: + specifier: ^6.3.7 + version: 6.3.7 ufo: specifier: 1.3.1 version: 1.3.1 @@ -4538,6 +4547,16 @@ packages: - '@tiptap/pm' dev: false + /@tiptap/suggestion@2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12): + resolution: {integrity: sha512-rhlLWwVkOodBGRMK0mAmE34l2a+BqM2Y7q1ViuQRBhs/6sZ8d83O4hARHKVwqT5stY4i1l7d7PoemV3uAGI6+g==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.12(@tiptap/pm@2.1.12) + '@tiptap/pm': 2.1.12 + dev: false + /@tiptap/vue-3@2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)(vue@3.3.6): resolution: {integrity: sha512-2CtNUzt+e7sgvIjxPOyBwoiRcuCHNeJzW+XGxNK2uCWlAKp/Yw3boJ51d51UuIbj9RitGHJ5GpCdLJoL7SDiQA==} peerDependencies: diff --git a/src/components/input/editor/TipTap.vue b/src/components/input/editor/TipTap.vue index a03321023..6da6de9bc 100644 --- a/src/components/input/editor/TipTap.vue +++ b/src/components/input/editor/TipTap.vue @@ -46,6 +46,9 @@ import CharacterCount from '@tiptap/extension-character-count' import StarterKit from '@tiptap/starter-kit' import {EditorContent, useEditor, VueNodeViewRenderer} from '@tiptap/vue-3' +import Commands from './commands' +import suggestion from './suggestion' + // load all highlight.js languages import {lowlight} from 'lowlight' @@ -199,6 +202,10 @@ const editor = useEditor({ // return VueNodeViewRenderer(CodeBlock) // }, // }).configure({ lowlight }), + + Commands.configure({ + suggestion, + }), ], onUpdate: () => { // HTML diff --git a/src/components/input/editor/commands.js b/src/components/input/editor/commands.ts similarity index 74% rename from src/components/input/editor/commands.js rename to src/components/input/editor/commands.ts index a16f097c9..189d567e7 100644 --- a/src/components/input/editor/commands.js +++ b/src/components/input/editor/commands.ts @@ -1,6 +1,8 @@ import { Extension } from '@tiptap/core' import Suggestion from '@tiptap/suggestion' +// Copied and adjusted from https://github.com/ueberdosis/tiptap/tree/252acb32d27a0f9af14813eeed83d8a50059a43a/demos/src/Experiments/Commands/Vue + export default Extension.create({ name: 'commands', diff --git a/src/components/input/editor/suggestion.js b/src/components/input/editor/suggestion.ts similarity index 100% rename from src/components/input/editor/suggestion.js rename to src/components/input/editor/suggestion.ts -- 2.40.1 From e81c98fe5b67f797c16c841e3ead8e02e33c37e3 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 21 Oct 2023 11:52:20 +0200 Subject: [PATCH 24/66] chore(editor): format --- src/components/input/editor/CommandsList.vue | 11 +- src/components/input/editor/commands.ts | 40 ++-- src/components/input/editor/suggestion.ts | 193 ++++++++++--------- 3 files changed, 121 insertions(+), 123 deletions(-) diff --git a/src/components/input/editor/CommandsList.vue b/src/components/input/editor/CommandsList.vue index a5f5c8048..4b8f55436 100644 --- a/src/components/input/editor/CommandsList.vue +++ b/src/components/input/editor/CommandsList.vue @@ -44,7 +44,7 @@ export default { }, methods: { - onKeyDown({ event }) { + onKeyDown({event}) { if (event.key === 'ArrowUp') { this.upHandler() return true @@ -86,19 +86,16 @@ export default { } - \ No newline at end of file diff --git a/src/components/input/editor/TipTap.vue b/src/components/input/editor/TipTap.vue index 6da6de9bc..d6abeae76 100644 --- a/src/components/input/editor/TipTap.vue +++ b/src/components/input/editor/TipTap.vue @@ -47,7 +47,7 @@ import StarterKit from '@tiptap/starter-kit' import {EditorContent, useEditor, VueNodeViewRenderer} from '@tiptap/vue-3' import Commands from './commands' -import suggestion from './suggestion' +import suggestionSetup from './suggestion' // load all highlight.js languages import {lowlight} from 'lowlight' @@ -58,6 +58,9 @@ import type {ITask} from '@/modelTypes/ITask' import type {IAttachment} from '@/modelTypes/IAttachment' import AttachmentModel from '@/models/attachment' import AttachmentService from '@/services/attachment' +import {useI18n} from 'vue-i18n' + +const {t} = useI18n() // const CustomDocument = Document.extend({ // content: 'taskList', @@ -204,7 +207,7 @@ const editor = useEditor({ // }).configure({ lowlight }), Commands.configure({ - suggestion, + suggestion: suggestionSetup(t), }), ], onUpdate: () => { diff --git a/src/components/input/editor/suggestion.ts b/src/components/input/editor/suggestion.ts index 64c8dc3e1..cf47d10f2 100644 --- a/src/components/input/editor/suggestion.ts +++ b/src/components/input/editor/suggestion.ts @@ -3,112 +3,212 @@ import tippy from 'tippy.js' import CommandsList from './CommandsList.vue' -export default { - items: ({query}: { query: string }) => { - return [ - { - title: 'H1', - command: ({editor, range}) => { - editor - .chain() - .focus() - .deleteRange(range) - .setNode('heading', {level: 1}) - .run() +export default function suggestionSetup(t) { + return { + items: ({query}: { query: string }) => { + return [ + { + title: t('input.editor.text'), + description: t('input.editor.textTooltip'), + icon: 'fa-font', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .setNode('paragraph', {level: 1}) + .run() + }, }, - }, - { - title: 'H2', - description: 'Lorem ipsum', - command: ({editor, range}) => { - editor - .chain() - .focus() - .deleteRange(range) - .setNode('heading', {level: 2}) - .run() + { + title: t('input.editor.heading1'), + description: t('input.editor.heading1Tooltip'), + icon: 'fa-header', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .setNode('heading', {level: 1}) + .run() + }, }, - }, - { - title: 'bold', - command: ({editor, range}) => { - editor - .chain() - .focus() - .deleteRange(range) - .setMark('bold') - .run() + { + title: t('input.editor.heading2'), + description: t('input.editor.heading2Tooltip'), + icon: 'fa-header', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .setNode('heading', {level: 2}) + .run() + }, }, - }, - { - title: 'italic', - command: ({editor, range}) => { - editor - .chain() - .focus() - .deleteRange(range) - .setMark('italic') - .run() + { + title: t('input.editor.heading3'), + description: t('input.editor.heading3Tooltip'), + icon: 'fa-header', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .setNode('heading', {level: 2}) + .run() + }, }, - }, - ].filter(item => item.title.toLowerCase().startsWith(query.toLowerCase())).slice(0, 10) - }, + { + title: t('input.editor.bulletList'), + description: t('input.editor.bulletListTooltip'), + icon: 'fa-list-ul', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .toggleBulletList() + .run() + }, + }, + { + title: t('input.editor.orderedList'), + description: t('input.editor.orderedListTooltip'), + icon: 'fa-list-ol', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .toggleOrderedList() + .run() + }, + }, + { + title: t('input.editor.taskList'), + description: t('input.editor.taskListTooltip'), + icon: 'fa-list-check', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .toggleTaskList() + .run() + }, + }, + { + title: t('input.editor.quote'), + description: t('input.editor.quoteTooltip'), + icon: 'fa-quote-right', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .toggleBlockquote() + .run() + }, + }, + { + title: t('input.editor.code'), + description: t('input.editor.codeTooltip'), + icon: 'fa-code', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .toggleCodeBlock() + .run() + }, + }, + // { + // title: t('input.editor.')'Image', + // description: t('input.editor.')'Upload an image from your computer', + // icon: 'fa-image', + // command: ({editor, range}) => { + // editor + // .chain() + // .focus() + // .deleteRange(range) + // .toggle() + // .run() + // }, + // }, + { + title: t('input.editor.horizontalRule'), + description: t('input.editor.horizontalRuleTooltip'), + icon: 'fa-ruler-horizontal', + command: ({editor, range}) => { + editor + .chain() + .focus() + .deleteRange(range) + .setHorizontalRule() + .run() + }, + }, + ].filter(item => item.title.toLowerCase().startsWith(query.toLowerCase())) + }, - render: () => { - let component: VueRenderer - let popup + render: () => { + let component: VueRenderer + let popup - return { - onStart: props => { - component = new VueRenderer(CommandsList, { - // using vue 2: - // parent: this, - // propsData: props, - props, - editor: props.editor, - }) + return { + onStart: props => { + component = new VueRenderer(CommandsList, { + // using vue 2: + // parent: this, + // propsData: props, + props, + editor: props.editor, + }) - if (!props.clientRect) { - return - } + if (!props.clientRect) { + return + } - popup = tippy('body', { - getReferenceClientRect: props.clientRect, - appendTo: () => document.body, - content: component.element, - showOnCreate: true, - interactive: true, - trigger: 'manual', - placement: 'bottom-start', - }) - }, + popup = tippy('body', { + getReferenceClientRect: props.clientRect, + appendTo: () => document.body, + content: component.element, + showOnCreate: true, + interactive: true, + trigger: 'manual', + placement: 'bottom-start', + }) + }, - onUpdate(props) { - component.updateProps(props) + onUpdate(props) { + component.updateProps(props) - if (!props.clientRect) { - return - } + if (!props.clientRect) { + return + } - popup[0].setProps({ - getReferenceClientRect: props.clientRect, - }) - }, + popup[0].setProps({ + getReferenceClientRect: props.clientRect, + }) + }, - onKeyDown(props) { - if (props.event.key === 'Escape') { - popup[0].hide() + onKeyDown(props) { + if (props.event.key === 'Escape') { + popup[0].hide() - return true - } + return true + } - return component.ref?.onKeyDown(props) - }, + return component.ref?.onKeyDown(props) + }, - onExit() { - popup[0].destroy() - component.destroy() - }, - } - }, + onExit() { + popup[0].destroy() + component.destroy() + }, + } + }, + } } \ No newline at end of file diff --git a/src/components/misc/Icon.ts b/src/components/misc/Icon.ts index 5300d07a2..cc8aed567 100644 --- a/src/components/misc/Icon.ts +++ b/src/components/misc/Icon.ts @@ -73,7 +73,7 @@ import { faUnlink, faParagraph, faTable, - faX, faArrowTurnDown, faListCheck, faXmark, faXmarksLines, + faX, faArrowTurnDown, faListCheck, faXmark, faXmarksLines, faFont, faRulerHorizontal, } from '@fortawesome/free-solid-svg-icons' import { faBellSlash, @@ -183,6 +183,8 @@ library.add(faArrowTurnDown) library.add(faListCheck) library.add(faXmark) library.add(faXmarksLines) +library.add(faFont) +library.add(faRulerHorizontal) // overwriting the wrong types export default FontAwesomeIcon as unknown as FontAwesomeIconFixedTypes \ No newline at end of file diff --git a/src/i18n/lang/en.json b/src/i18n/lang/en.json index e15670dd1..9cd8fafbd 100644 --- a/src/i18n/lang/en.json +++ b/src/i18n/lang/en.json @@ -514,24 +514,37 @@ "edit": "Edit", "done": "Done", "heading1": "Heading 1", + "heading1Tooltip": "Big section heading.", "heading2": "Heading 2", + "heading2Tooltip": "Medium section heading.", "heading3": "Heading 3", + "heading3Tooltip": "Smaller section header.", "headingSmaller": "Heading Smaller", "headingBigger": "Heading Bigger", "bold": "Bold", "italic": "Italic", "strikethrough": "Strikethrough", "code": "Code", + "codeTooltip": "Capture a code snippet.", "quote": "Quote", + "quoteTooltip": "Capture a quote.", + "bulletList": "Bullet list", + "bulletListTooltip": "Create a simple bullet list.", "unorderedList": "Unordered List", "orderedList": "Ordered List", + "orderedListTooltip": "Create a list with numbering.", "cleanBlock": "Clean Block", "link": "Link", "image": "Image", "table": "Table", "horizontalRule": "Horizontal Rule", + "horizontalRuleTooltip": "Divide a section.", "sideBySide": "Side By Side", "guide": "Guide", + "text": "Text", + "textTooltip": "Just start typing with plain text.", + "taskList": "Task list", + "taskListTooltip": "Track tasks with a to-do list.", "table": { "insert": "Insert table", "addColumnBefore": "Add column before", -- 2.40.1 From 17c23d94632293a463752b4dc44db1f9bafa6e2a Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 21 Oct 2023 13:28:59 +0200 Subject: [PATCH 26/66] feat(editor): make image upload work via slash command --- src/components/input/editor/EditorToolbar.vue | 33 ++------------ src/components/input/editor/TipTap.vue | 43 ++++++++++++++++++- src/components/input/editor/suggestion.ts | 26 +++++------ src/i18n/lang/en.json | 1 + 4 files changed, 58 insertions(+), 45 deletions(-) diff --git a/src/components/input/editor/EditorToolbar.vue b/src/components/input/editor/EditorToolbar.vue index aac57a429..8a676c09b 100644 --- a/src/components/input/editor/EditorToolbar.vue +++ b/src/components/input/editor/EditorToolbar.vue @@ -151,7 +151,7 @@
- + @@ -369,7 +369,6 @@
- @@ -388,40 +387,14 @@ const { uploadCallback?: UploadCallback, }>() -const emit = defineEmits(['imageAdded']) - const tableMode = ref(false) -const uploadInputRef = ref(null) function toggleTableMode() { tableMode.value = !tableMode.value } -function addImage() { - - if (typeof uploadCallback !== 'undefined') { - const files = uploadInputRef.value?.files - - if (!files || files.length === 0) { - return - } - - uploadCallback(files).then(urls => { - urls.forEach(url => { - editor?.chain().focus().setImage({src: url}).run() - }) - emit('imageAdded') - }) - - return - } - - const url = window.prompt('URL') - - if (url) { - editor?.chain().focus().setImage({src: url}).run() - emit('imageAdded') - } +function openImagePicker() { + document.getElementById('tiptap__image-upload').click() } function setLink() { diff --git a/src/components/input/editor/TipTap.vue b/src/components/input/editor/TipTap.vue index d6abeae76..00136cd80 100644 --- a/src/components/input/editor/TipTap.vue +++ b/src/components/input/editor/TipTap.vue @@ -4,12 +4,18 @@ v-if="editor" :editor="editor" :upload-callback="uploadCallback" - @image-added="onImageAdded" /> + @@ -205,7 +211,7 @@ const editor = useEditor({ // return VueNodeViewRenderer(CodeBlock) // }, // }).configure({ lowlight }), - + Commands.configure({ suggestion: suggestionSetup(t), }), @@ -235,6 +241,39 @@ watch(inputHTML, (value) => { }) onBeforeUnmount(() => editor.value?.destroy()) + +const uploadInputRef = ref(null) + +function addImage() { + + if (typeof uploadCallback !== 'undefined') { + const files = uploadInputRef.value?.files + + if (!files || files.length === 0) { + return + } + + uploadCallback(files).then(urls => { + urls.forEach(url => { + editor.value + .chain() + .focus() + .setImage({src: url}) + .run() + }) + onImageAdded() + }) + + return + } + + const url = window.prompt('URL') + + if (url) { + editor.value.chain().focus().setImage({src: url}).run() + onImageAdded() + } +} diff --git a/src/components/misc/Icon.ts b/src/components/misc/Icon.ts index cc8aed567..d50e3953d 100644 --- a/src/components/misc/Icon.ts +++ b/src/components/misc/Icon.ts @@ -73,7 +73,7 @@ import { faUnlink, faParagraph, faTable, - faX, faArrowTurnDown, faListCheck, faXmark, faXmarksLines, faFont, faRulerHorizontal, + faX, faArrowTurnDown, faListCheck, faXmark, faXmarksLines, faFont, faRulerHorizontal, faUnderline, } from '@fortawesome/free-solid-svg-icons' import { faBellSlash, @@ -185,6 +185,7 @@ library.add(faXmark) library.add(faXmarksLines) library.add(faFont) library.add(faRulerHorizontal) +library.add(faUnderline) // overwriting the wrong types export default FontAwesomeIcon as unknown as FontAwesomeIconFixedTypes \ No newline at end of file -- 2.40.1 From d75a963d0801aa64c962b2ce6427d6699ab05540 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 21 Oct 2023 14:06:47 +0200 Subject: [PATCH 28/66] feat(editor): add code highlighting --- src/components/input/editor/TipTap.vue | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/input/editor/TipTap.vue b/src/components/input/editor/TipTap.vue index 0288ad310..9af963bcb 100644 --- a/src/components/input/editor/TipTap.vue +++ b/src/components/input/editor/TipTap.vue @@ -263,11 +263,9 @@ const editor = useEditor({ // // character count // CharacterCount, - // CodeBlockLowlight.extend({ - // addNodeView() { - // return VueNodeViewRenderer(CodeBlock) - // }, - // }).configure({ lowlight }), + CodeBlockLowlight.configure({ + lowlight, + }), Commands.configure({ suggestion: suggestionSetup(t), -- 2.40.1 From 0b2aa723a6343bc90925e235aba18160f736793d Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 21 Oct 2023 14:07:39 +0200 Subject: [PATCH 29/66] feat(editor): open links when clicking on them --- src/components/input/editor/TipTap.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/input/editor/TipTap.vue b/src/components/input/editor/TipTap.vue index 9af963bcb..0a2af83e7 100644 --- a/src/components/input/editor/TipTap.vue +++ b/src/components/input/editor/TipTap.vue @@ -239,7 +239,7 @@ const editor = useEditor({ Typography, Underline, Link.configure({ - openOnClick: false, + openOnClick: true, validate: (href: string) => /^https?:\/\//.test(href), }), Table.configure({ -- 2.40.1 From 66c37f10e0dbf7e1ae5872fd4c69d891b0030fb0 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 21 Oct 2023 14:10:26 +0200 Subject: [PATCH 30/66] chore(editor): cleanup --- src/components/input/editor/CodeBlock.vue | 46 ---------------------- src/components/input/editor/TipTap.vue | 47 ++--------------------- 2 files changed, 4 insertions(+), 89 deletions(-) delete mode 100644 src/components/input/editor/CodeBlock.vue diff --git a/src/components/input/editor/CodeBlock.vue b/src/components/input/editor/CodeBlock.vue deleted file mode 100644 index 59fc6a4d6..000000000 --- a/src/components/input/editor/CodeBlock.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/components/input/editor/TipTap.vue b/src/components/input/editor/TipTap.vue index 0a2af83e7..eb01a54b5 100644 --- a/src/components/input/editor/TipTap.vue +++ b/src/components/input/editor/TipTap.vue @@ -79,7 +79,7 @@ const tiptapRegex = new RegExp(`${TIPTAP_TEXT_VALUE_PREFIX}`, 's') -- 2.40.1 From 34420b623cdebf4f7a9beb6443207cae64c5b453 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 21 Oct 2023 19:29:19 +0200 Subject: [PATCH 41/66] fix(editor): use edit enable --- src/components/input/editor/TipTap.vue | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/components/input/editor/TipTap.vue b/src/components/input/editor/TipTap.vue index 1364bcfb1..d92942636 100644 --- a/src/components/input/editor/TipTap.vue +++ b/src/components/input/editor/TipTap.vue @@ -1,12 +1,12 @@