diff --git a/cypress/e2e/misc/editor.spec.ts b/cypress/e2e/misc/editor.spec.ts
deleted file mode 100644
index 0a1b6429..00000000
--- a/cypress/e2e/misc/editor.spec.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import {createFakeUserAndLogin} from '../../support/authenticateUser'
-
-import {TaskFactory} from '../../factories/task'
-import {ProjectFactory} from '../../factories/project'
-import {UserProjectFactory} from '../../factories/users_project'
-import {BucketFactory} from '../../factories/bucket'
-
-describe('Editor', () => {
- createFakeUserAndLogin()
-
- beforeEach(() => {
- ProjectFactory.create(1)
- BucketFactory.create(1)
- TaskFactory.truncate()
- UserProjectFactory.truncate()
- })
-
- it('Has a preview with checkable checkboxes', () => {
- const tasks = TaskFactory.create(1, {
- description: `# Test Heading
-* Bullet 1
-* Bullet 2
-
-* [ ] Checklist
-* [x] Checklist checked
-`,
- bucket_id: 1,
- })
-
- cy.visit(`/tasks/${tasks[0].id}`)
- cy.get('input[type=checkbox][data-checkbox-num=0]')
- .click()
-
- cy.get('.task-view .details.content.description h3 span.is-small.has-text-success')
- .contains('Saved!')
- .should('exist')
- cy.get('.preview.content')
- .should('contain', 'Test Heading')
- })
-})
\ No newline at end of file
diff --git a/cypress/e2e/task/task.spec.ts b/cypress/e2e/task/task.spec.ts
index 5963a759..c2019f08 100644
--- a/cypress/e2e/task/task.spec.ts
+++ b/cypress/e2e/task/task.spec.ts
@@ -24,7 +24,7 @@ function addLabelToTaskAndVerify(labelTitle: string) {
.first()
.click()
- cy.get('.global-notification', { timeout: 4000 })
+ cy.get('.global-notification', {timeout: 4000})
.should('contain', 'Success')
cy.get('.task-view .details.labels-list .multiselect .input-wrapper span.tag')
.should('exist')
@@ -122,7 +122,7 @@ describe('Task', () => {
const tasks = TaskFactory.create(1, {
id: 1,
index: 1,
- description: 'Lorem ipsum dolor sit amet.'
+ description: 'Lorem ipsum dolor sit amet.',
})
cy.visit(`/tasks/${tasks[0].id}`)
@@ -143,7 +143,7 @@ describe('Task', () => {
id: 1,
index: 1,
done: true,
- done_at: new Date().toISOString()
+ done_at: new Date().toISOString(),
})
cy.visit(`/tasks/${tasks[0].id}`)
@@ -196,13 +196,13 @@ describe('Task', () => {
it('Can edit the description', () => {
const tasks = TaskFactory.create(1, {
id: 1,
- description: 'Lorem ipsum dolor sit amet.'
+ description: 'Lorem ipsum dolor sit amet.',
})
cy.visit(`/tasks/${tasks[0].id}`)
- cy.get('.task-view .details.content.description .editor button')
+ cy.get('.task-view .details.content.description .tiptap button.done-edit')
.click()
- cy.get('.task-view .details.content.description .editor .vue-easymde .EasyMDEContainer .CodeMirror-scroll')
+ cy.get('.task-view .details.content.description .tiptap__editor .tiptap.ProseMirror')
.type('{selectall}New Description')
cy.get('[data-cy="saveEditor"]')
.contains('Save')
@@ -219,7 +219,7 @@ describe('Task', () => {
})
cy.visit(`/tasks/${tasks[0].id}`)
- cy.get('.task-view .comments .media.comment .editor .vue-easymde .EasyMDEContainer .CodeMirror-scroll')
+ cy.get('.task-view .comments .media.comment .tiptap__editor .tiptap.ProseMirror')
.should('be.visible')
.type('{selectall}New Comment')
cy.get('.task-view .comments .media.comment .button:not([disabled])')
@@ -227,7 +227,7 @@ describe('Task', () => {
.should('be.visible')
.click()
- cy.get('.task-view .comments .media.comment .editor')
+ cy.get('.task-view .comments .media.comment .tiptap__editor')
.should('contain', 'New Comment')
cy.get('.global-notification')
.should('contain', 'Success')
@@ -236,7 +236,7 @@ describe('Task', () => {
it('Can move a task to another project', () => {
const projects = ProjectFactory.create(2)
BucketFactory.create(2, {
- project_id: '{increment}'
+ project_id: '{increment}',
})
const tasks = TaskFactory.create(1, {
id: 1,
@@ -380,7 +380,7 @@ describe('Task', () => {
addLabelToTaskAndVerify(labels[0].title)
})
-
+
it('Can add a label to a task and it shows up on the kanban board afterwards', () => {
const tasks = TaskFactory.create(1, {
id: 1,
@@ -389,18 +389,18 @@ describe('Task', () => {
})
const labels = LabelFactory.create(1)
LabelTaskFactory.truncate()
-
+
cy.visit(`/projects/${projects[0].id}/kanban`)
-
+
cy.get('.bucket .task')
.contains(tasks[0].title)
.click()
-
+
addLabelToTaskAndVerify(labels[0].title)
-
+
cy.get('.modal-content .close')
.click()
-
+
cy.get('.bucket .task')
.should('contain.text', labels[0].title)
})
@@ -461,7 +461,7 @@ describe('Task', () => {
cy.get('.global-notification')
.should('contain', 'Success')
})
-
+
it('Can set a reminder', () => {
TaskReminderFactory.truncate()
const tasks = TaskFactory.create(1, {
@@ -543,7 +543,7 @@ describe('Task', () => {
cy.get('.global-notification')
.should('contain', 'Success')
})
-
+
it('Allows to set a custom relative reminder when the task already has a due date', () => {
TaskReminderFactory.truncate()
const tasks = TaskFactory.create(1, {
@@ -579,7 +579,7 @@ describe('Task', () => {
cy.get('.global-notification')
.should('contain', 'Success')
})
-
+
it('Allows to set a fixed reminder when the task already has a due date', () => {
TaskReminderFactory.truncate()
const tasks = TaskFactory.create(1, {
@@ -609,7 +609,7 @@ describe('Task', () => {
cy.get('.global-notification')
.should('contain', 'Success')
})
-
+
it('Can set a priority for a task', () => {
const tasks = TaskFactory.create(1, {
id: 1,
@@ -647,7 +647,7 @@ describe('Task', () => {
.select('50%')
cy.get('.global-notification')
.should('contain', 'Success')
-
+
cy.wait(200)
cy.get('.task-view .columns.details .column')
@@ -656,7 +656,7 @@ describe('Task', () => {
.should('be.visible')
.should('have.value', '0.5')
})
-
+
it('Can add an attachment to a task', () => {
TaskAttachmentFactory.truncate()
const tasks = TaskFactory.create(1, {
@@ -691,35 +691,119 @@ describe('Task', () => {
cy.get('.bucket .task .footer .icon svg.fa-paperclip')
.should('exist')
})
-
+
it('Can check items off a checklist', () => {
const tasks = TaskFactory.create(1, {
id: 1,
description: `
-This is a checklist:
-
-* [ ] one item
-* [ ] another item
-* [ ] third item
-* [ ] fourth item
-* [x] and this one is already done
-`,
+
`,
})
cy.visit(`/tasks/${tasks[0].id}`)
-
+
cy.get('.task-view .checklist-summary')
.should('contain.text', '1 of 5 tasks')
- cy.get('.editor .content ul > li input[type=checkbox]')
+ cy.get('.tiptap__editor ul > li input[type=checkbox]')
.eq(2)
.click()
-
- cy.get('.editor .content ul > li input[type=checkbox]')
+
+ cy.get('.task-view .details.content.description h3 span.is-small.has-text-success')
+ .contains('Saved!')
+ .should('exist')
+ cy.get('.tiptap__editor ul > li input[type=checkbox]')
.eq(2)
.should('be.checked')
- cy.get('.editor .content input[type=checkbox]')
+ cy.get('.tiptap__editor input[type=checkbox]')
.should('have.length', 5)
cy.get('.task-view .checklist-summary')
.should('contain.text', '2 of 5 tasks')
})
+
+ it('Should use the editor to render description', () => {
+ const tasks = TaskFactory.create(1, {
+ id: 1,
+ description: `
+Lorem Ipsum
+Dolor sit amet
+`,
+ })
+ cy.visit(`/tasks/${tasks[0].id}`)
+
+ cy.get('.tiptap__editor ul > li input[type=checkbox]')
+ .should('exist')
+ cy.get('.tiptap__editor h1')
+ .contains('Lorem Ipsum')
+ .should('exist')
+ cy.get('.tiptap__editor p')
+ .contains('Dolor sit amet')
+ .should('exist')
+ })
+
+ it.only('Should render an image from attachment', async () => {
+
+ TaskAttachmentFactory.truncate()
+
+ const tasks = TaskFactory.create(1, {
+ id: 1,
+ description: '',
+ })
+
+ cy.readFile('cypress/fixtures/image.jpg', null).then(file => {
+
+ const formData = new FormData()
+ formData.append('files', new Blob([file]), 'image.jpg')
+
+ cy.request({
+ method: 'PUT',
+ url: `${Cypress.env('API_URL')}/tasks/${tasks[0].id}/attachments`,
+ headers: {
+ 'Authorization': `Bearer ${window.localStorage.getItem('token')}`,
+ 'Content-Type': 'multipart/form-data',
+ },
+ body: formData,
+ })
+ .then(({body}) => {
+ const dec = new TextDecoder('utf-8')
+ const {success} = JSON.parse(dec.decode(body))
+
+ TaskFactory.create(1, {
+ id: 1,
+ description: ``,
+ })
+
+ cy.visit(`/tasks/${tasks[0].id}`)
+
+ cy.get('.tiptap__editor img')
+ .should('be.visible')
+ .and(($img) => {
+ // "naturalWidth" and "naturalHeight" are set when the image loads
+ expect($img[0].naturalWidth).to.be.greaterThan(0)
+ })
+
+ })
+ })
+ })
})
})
diff --git a/package.json b/package.json
index 5b36f668..c1804d81 100644
--- a/package.json
+++ b/package.json
@@ -55,30 +55,64 @@
"@kyvg/vue3-notification": "3.0.2",
"@sentry/tracing": "7.74.0",
"@sentry/vue": "7.74.0",
+ "@tiptap/core": "2.1.12",
+ "@tiptap/extension-blockquote": "2.1.12",
+ "@tiptap/extension-bold": "2.1.12",
+ "@tiptap/extension-bullet-list": "2.1.12",
+ "@tiptap/extension-code": "2.1.12",
+ "@tiptap/extension-code-block-lowlight": "2.0.3",
+ "@tiptap/extension-document": "2.0.3",
+ "@tiptap/extension-dropcursor": "2.1.12",
+ "@tiptap/extension-gapcursor": "2.1.12",
+ "@tiptap/extension-hard-break": "2.1.12",
+ "@tiptap/extension-heading": "2.1.12",
+ "@tiptap/extension-history": "2.1.12",
+ "@tiptap/extension-horizontal-rule": "2.1.12",
+ "@tiptap/extension-image": "2.0.3",
+ "@tiptap/extension-italic": "2.1.12",
+ "@tiptap/extension-link": "2.0.3",
+ "@tiptap/extension-list-item": "2.1.12",
+ "@tiptap/extension-ordered-list": "2.1.12",
+ "@tiptap/extension-paragraph": "2.1.12",
+ "@tiptap/extension-placeholder": "2.1.12",
+ "@tiptap/extension-strike": "2.1.12",
+ "@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-text": "2.1.12",
+ "@tiptap/extension-typography": "2.0.3",
+ "@tiptap/extension-underline": "2.1.12",
+ "@tiptap/pm": "2.1.12",
+ "@tiptap/suggestion": "2.1.12",
+ "@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",
"blurhash": "2.0.5",
"bulma-css-variables": "0.9.33",
"camel-case": "4.1.2",
- "codemirror": "5.65.15",
"date-fns": "2.30.0",
"dayjs": "1.11.10",
"dompurify": "3.0.6",
- "easymde": "2.18.0",
"fast-deep-equal": "3.1.3",
"flatpickr": "4.6.13",
"flexsearch": "0.7.31",
"floating-vue": "2.0.0-beta.24",
- "highlight.js": "11.9.0",
"is-touch-device": "1.0.1",
"klona": "2.0.6",
"lodash.debounce": "4.0.8",
- "marked": "9.1.2",
+ "lowlight": "2.7.0",
"pinia": "2.1.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 9637ace4..31cc1cc9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -40,6 +40,114 @@ 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-blockquote':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/extension-bold':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/extension-bullet-list':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/extension-code':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@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-dropcursor':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)
+ '@tiptap/extension-gapcursor':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)
+ '@tiptap/extension-hard-break':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/extension-heading':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/extension-history':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)
+ '@tiptap/extension-horizontal-rule':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)
+ '@tiptap/extension-image':
+ specifier: 2.0.3
+ version: 2.0.3(@tiptap/core@2.1.12)
+ '@tiptap/extension-italic':
+ specifier: 2.1.12
+ version: 2.1.12(@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-list-item':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/extension-ordered-list':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/extension-paragraph':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/extension-placeholder':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)
+ '@tiptap/extension-strike':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@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-text':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/extension-typography':
+ specifier: 2.0.3
+ version: 2.0.3(@tiptap/core@2.1.12)
+ '@tiptap/extension-underline':
+ specifier: 2.1.12
+ version: 2.1.12(@tiptap/core@2.1.12)
+ '@tiptap/pm':
+ specifier: 2.1.12
+ version: 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)
+ '@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)
@@ -58,9 +166,6 @@ dependencies:
camel-case:
specifier: 4.1.2
version: 4.1.2
- codemirror:
- specifier: 5.65.15
- version: 5.65.15
date-fns:
specifier: 2.30.0
version: 2.30.0
@@ -70,9 +175,6 @@ dependencies:
dompurify:
specifier: 3.0.6
version: 3.0.6
- easymde:
- specifier: 2.18.0
- version: 2.18.0
fast-deep-equal:
specifier: 3.1.3
version: 3.1.3
@@ -85,9 +187,6 @@ dependencies:
floating-vue:
specifier: 2.0.0-beta.24
version: 2.0.0-beta.24(vue@3.3.6)
- highlight.js:
- specifier: 11.9.0
- version: 11.9.0
is-touch-device:
specifier: 1.0.1
version: 1.0.1
@@ -97,9 +196,9 @@ dependencies:
lodash.debounce:
specifier: 4.0.8
version: 4.0.8
- marked:
- specifier: 9.1.2
- version: 9.1.2
+ lowlight:
+ specifier: 2.7.0
+ version: 2.7.0
pinia:
specifier: 2.1.7
version: 2.1.7(typescript@5.2.2)(vue@3.3.6)
@@ -112,6 +211,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
@@ -171,9 +273,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 +285,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.52.0)(typescript@5.2.2)
@@ -3882,6 +3978,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
@@ -4197,6 +4325,346 @@ 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-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-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-placeholder@2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12):
+ resolution: {integrity: sha512-K52o7B1zkP4vaVy3z4ZwHn+tQy6KlXtedj1skLg+796ImwH2GYS5z6MFOTfKzBO2hLncUzLco/s0C5PLCD6SDw==}
+ 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-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/extension-underline@2.1.12(@tiptap/core@2.1.12):
+ resolution: {integrity: sha512-NwwdhFT8gDD0VUNLQx85yFBhP9a8qg8GPuxlGzAP/lPTV8Ubh3vSeQ5N9k2ZF/vHlEvnugzeVCbmYn7wf8vn1g==}
+ 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/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:
+ '@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'}
@@ -4232,6 +4700,7 @@ packages:
resolution: {integrity: sha512-SFSj5Tb/mtQoVgaltsipdRGG1PkcFu/L0OXPNBGCXYUQtwsNoAGRNNHOTl1jYcQUcEI77EiUfk94bgETTbSo/A==}
dependencies:
'@types/tern': 0.23.4
+ dev: true
/@types/dompurify@3.0.4:
resolution: {integrity: sha512-1Jk8S/IRzNSbwQRbuGuLFHviwxQ8pX81ZEW3INY9432Cwb4VedkBYan8gSIXVLOLHBtimOmUTEYphjRVmo+30g==}
@@ -4274,9 +4743,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==}
@@ -4292,6 +4767,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:
@@ -4300,7 +4781,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==}
@@ -4309,10 +4789,6 @@ packages:
'@types/mdurl': 1.0.2
dev: true
- /@types/marked@4.3.1:
- resolution: {integrity: sha512-vSSbKZFbNktrQ15v7o1EaH78EbWV+sPQbPjHG+Cp8CaNcPFUEfjZ0Iml/V0bFDwsTlYe8o6XC5Hfdp91cqPV2g==}
- dev: false
-
/@types/marked@5.0.2:
resolution: {integrity: sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg==}
dev: true
@@ -4333,6 +4809,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:
@@ -4364,19 +4848,28 @@ 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
+ dev: true
+
+ /@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
@@ -5421,6 +5914,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
@@ -5593,16 +6091,6 @@ packages:
engines: {node: '>=0.8'}
dev: true
- /codemirror-spell-checker@1.1.2:
- resolution: {integrity: sha1-HGYPkIlIPMtRE7m6nKGcP0mTNx4=}
- dependencies:
- typo-js: 1.2.1
- dev: false
-
- /codemirror@5.65.15:
- resolution: {integrity: sha512-YC4EHbbwQeubZzxLl5G4nlbLc1T21QTrKGaOal/Pkm9dVDMZXMH7+ieSPEOZCtO9I68i8/oteJKOxzHC2zR+0g==}
- dev: false
-
/color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
@@ -5731,7 +6219,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==}
@@ -5922,6 +6409,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'}
@@ -6040,6 +6531,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:
@@ -6187,16 +6683,6 @@ packages:
resolution: {integrity: sha512-GJRqdiy2h+EXy6a8E6R+ubmqUM08BK0FWNq41k24fup6045biQ8NXxoXimiwegMQvFFV3t1emADdGNL1TlS61A==}
dev: false
- /easymde@2.18.0:
- resolution: {integrity: sha512-IxVVUxNWIoXLeqtBU4BLc+eS/ScYhT1Dcb6yF5Wchoj1iXAV+TIIDWx+NCaZhY7RcSHqDPKllbYq7nwGKILnoA==}
- dependencies:
- '@types/codemirror': 5.60.12
- '@types/marked': 4.3.1
- codemirror: 5.65.15
- codemirror-spell-checker: 1.1.2
- marked: 4.3.0
- dev: false
-
/ecc-jsbn@0.1.2:
resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==}
dependencies:
@@ -6261,6 +6747,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'}
@@ -6389,7 +6880,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==}
@@ -6639,6 +7129,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:
@@ -6794,6 +7290,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'}
@@ -7098,8 +7599,8 @@ packages:
tslib: 2.3.1
dev: true
- /highlight.js@11.9.0:
- resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==}
+ /highlight.js@11.6.0:
+ resolution: {integrity: sha512-ig1eqDzJaB0pqEvlPVIpSSyMaO92bH1N2rJpLMN/nX396wTpDA4Eq0uK+7I/2XG17pFaaKE0kjV/XPeGt7Evjw==}
engines: {node: '>=12.0.0'}
dev: false
@@ -7383,6 +7884,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'}
@@ -7464,6 +7972,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
@@ -7538,6 +8053,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
@@ -7795,6 +8315,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'}
@@ -7898,6 +8428,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:
@@ -7935,6 +8473,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'}
@@ -7983,16 +8525,15 @@ packages:
uc.micro: 1.0.6
dev: true
- /marked@4.3.0:
- resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==}
- engines: {node: '>= 12'}
- hasBin: true
- dev: false
-
- /marked@9.1.2:
- resolution: {integrity: sha512-qoKMJqK0w6vkLk8+KnKZAH6neUZSNaQqVZ/h2yZ9S7CbLuFHyS2viB0jnqcWF9UKjwsAbMrQtnQhdmdvOVOw9w==}
- engines: {node: '>= 16'}
+ /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
/mdn-data@2.0.28:
@@ -8005,7 +8546,6 @@ packages:
/mdurl@1.0.1:
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
- dev: true
/meow@7.1.1:
resolution: {integrity: sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==}
@@ -8268,6 +8808,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'}
@@ -8335,6 +8889,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'}
@@ -8982,6 +9540,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
@@ -9325,6 +10026,10 @@ packages:
'@rollup/rollup-win32-x64-msvc': 4.1.4
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'}
@@ -9839,6 +10544,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
@@ -9861,6 +10571,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
@@ -10010,6 +10726,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:
@@ -10021,13 +10742,8 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
- /typo-js@1.2.1:
- resolution: {integrity: sha512-bTGLjbD3WqZDR3CgEFkyi9Q/SS2oM29ipXrWfDb4M74ea69QwKAECVceYpaBu0GfdnASMg9Qfl67ttB23nePHg==}
- dev: false
-
/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==}
@@ -10524,7 +11240,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==}
diff --git a/renovate.json b/renovate.json
index b27d66ec..11e6826c 100644
--- a/renovate.json
+++ b/renovate.json
@@ -27,6 +27,13 @@
"histoire"
]
},
+ {
+ "groupName": "tiptap",
+ "matchPackagePrefixes": [
+ "@tiptap/",
+ "tiptap"
+ ]
+ },
{
"matchDepTypes": ["devDependencies"],
"groupName": "dev-dependencies",
diff --git a/src/components/input/AsyncEditor.ts b/src/components/input/AsyncEditor.ts
index f8001522..4196baf5 100644
--- a/src/components/input/AsyncEditor.ts
+++ b/src/components/input/AsyncEditor.ts
@@ -1,3 +1,5 @@
import {createAsyncComponent} from '@/helpers/createAsyncComponent'
-export default createAsyncComponent(() => import('@/components/input/editor.vue'))
\ No newline at end of file
+const TipTap = createAsyncComponent(() => import('@/components/input/editor/TipTap.vue'))
+
+export default TipTap
diff --git a/src/components/input/editor.vue b/src/components/input/editor.vue
deleted file mode 100644
index e4fe87a0..00000000
--- a/src/components/input/editor.vue
+++ /dev/null
@@ -1,444 +0,0 @@
-
-
-
-
-
bubbleNow()"
- @update:modelValue="handleInput"
- class="content"
- v-if="isEditActive"
- v-model="text"/>
-
-
-
-
-
- {{ emptyText }}
-
-
- {{ $t('input.editor.edit') }}
- .
-
-
-
-
- -
-
- {{ $t('input.editor.edit') }}
-
-
- {{ $t('misc.save') }}
-
-
- -
- {{ action.title }}
-
-
-
-
- -
-
- {{ $t('input.editor.edit') }}
-
-
-
-
- {{ $t('misc.save') }}
-
-
-
-
-
-
-
-
diff --git a/src/components/input/editor/CommandsList.vue b/src/components/input/editor/CommandsList.vue
new file mode 100644
index 00000000..6221f391
--- /dev/null
+++ b/src/components/input/editor/CommandsList.vue
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+ No result
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/input/editor/EditorToolbar.vue b/src/components/input/editor/EditorToolbar.vue
new file mode 100644
index 00000000..5173899e
--- /dev/null
+++ b/src/components/input/editor/EditorToolbar.vue
@@ -0,0 +1,439 @@
+
+
+
+
+
+
+
diff --git a/src/components/input/editor/TipTap.vue b/src/components/input/editor/TipTap.vue
new file mode 100644
index 00000000..62b73b98
--- /dev/null
+++ b/src/components/input/editor/TipTap.vue
@@ -0,0 +1,854 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+ {{ $t('input.editor.edit') }}
+
+
+
+
+ -
+
+ {{ $t('misc.save') }}
+
+
+ -
+
+ {{ $t('input.editor.edit') }}
+
+
+ -
+ {{ action.title }}
+
+
+
+ {{ $t('misc.save') }}
+
+
+
+
+
+
+
diff --git a/src/components/input/editor/commands.ts b/src/components/input/editor/commands.ts
new file mode 100644
index 00000000..f72de756
--- /dev/null
+++ b/src/components/input/editor/commands.ts
@@ -0,0 +1,28 @@
+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: 'slash-menu-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.ts b/src/components/input/editor/suggestion.ts
new file mode 100644
index 00000000..9ae6182a
--- /dev/null
+++ b/src/components/input/editor/suggestion.ts
@@ -0,0 +1,214 @@
+import {VueRenderer} from '@tiptap/vue-3'
+import tippy from 'tippy.js'
+
+import CommandsList from './CommandsList.vue'
+
+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: 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: 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: 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()
+ },
+ },
+ {
+ 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.imageTooltip'),
+ icon: 'fa-image',
+ command: ({editor, range}) => {
+ editor
+ .chain()
+ .focus()
+ .deleteRange(range)
+ .run()
+ document.getElementById('tiptap__image-upload').click()
+ },
+ },
+ {
+ 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
+
+ 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
diff --git a/src/components/input/editor/types.ts b/src/components/input/editor/types.ts
new file mode 100644
index 00000000..5fa5b3a8
--- /dev/null
+++ b/src/components/input/editor/types.ts
@@ -0,0 +1,6 @@
+export type UploadCallback = (files: File[] | FileList) => Promise
+
+export interface BottomAction {
+ title: string
+ action: () => void,
+}
diff --git a/src/components/input/editorConfig.ts b/src/components/input/editorConfig.ts
deleted file mode 100644
index e50e9aec..00000000
--- a/src/components/input/editorConfig.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import EasyMDE from 'easymde'
-import {i18n} from '@/i18n'
-
-export function createEasyMDEConfig({ placeholder, uploadImage, imageUploadFunction }) {
- return {
- autoDownloadFontAwesome: false,
- spellChecker: false,
- placeholder,
- uploadImage,
- imageUploadFunction,
- minHeight: '150px',
- sideBySideFullscreen: false,
- toolbar: [
- {
- name: 'heading-1',
- action: EasyMDE.toggleHeading1,
- title: i18n.global.t('input.editor.heading1'),
- icon: '',
- },
- {
- name: 'heading-2',
- action: EasyMDE.toggleHeading2,
- title: i18n.global.t('input.editor.heading2'),
- icon: '',
- },
- {
- name: 'heading-3',
- action: EasyMDE.toggleHeading3,
- title: i18n.global.t('input.editor.heading3'),
- icon: '',
- },
- {
- name: 'heading-smaller',
- action: EasyMDE.toggleHeadingSmaller,
- title: i18n.global.t('input.editor.headingSmaller'),
- icon: '',
- },
- {
- name: 'heading-bigger',
- action: EasyMDE.toggleHeadingBigger,
- title: i18n.global.t('input.editor.headingBigger'),
- icon: '',
- },
- '|',
- {
- name: 'bold',
- action: EasyMDE.toggleBold,
- title: i18n.global.t('input.editor.bold'),
- icon: '',
- },
- {
- name: 'italic',
- action: EasyMDE.toggleItalic,
- title: i18n.global.t('input.editor.italic'),
- icon: '',
- },
- {
- name: 'strikethrough',
- action: EasyMDE.toggleStrikethrough,
- title: i18n.global.t('input.editor.strikethrough'),
- icon: '',
- },
- {
- name: 'code',
- action: EasyMDE.toggleCodeBlock,
- title: i18n.global.t('input.editor.code'),
- icon: '',
- },
- {
- name: 'quote',
- action: EasyMDE.toggleBlockquote,
- title: i18n.global.t('input.editor.quote'),
- icon: '',
- },
- {
- name: 'unordered-list',
- action: EasyMDE.toggleUnorderedList,
- title: i18n.global.t('input.editor.unorderedList'),
- icon: '',
- },
- {
- name: 'ordered-list',
- action: EasyMDE.toggleOrderedList,
- title: i18n.global.t('input.editor.orderedList'),
- icon: '',
- },
- '|',
- {
- name: 'clean-block',
- action: EasyMDE.cleanBlock,
- title: i18n.global.t('input.editor.cleanBlock'),
- icon: '',
- },
- {
- name: 'link',
- action: EasyMDE.drawLink,
- title: i18n.global.t('input.editor.link'),
- icon: '',
- },
- {
- name: 'image',
- action: EasyMDE.drawImage,
- title: i18n.global.t('input.editor.image'),
- icon: '',
- },
- {
- name: 'table',
- action: EasyMDE.drawTable,
- title: i18n.global.t('input.editor.table'),
- icon: '',
- },
- {
- name: 'horizontal-rule',
- action: EasyMDE.drawHorizontalRule,
- title: i18n.global.t('input.editor.horizontalRule'),
- icon: '',
- },
- '|',
- {
- name: 'side-by-side',
- action: EasyMDE.toggleSideBySide,
- title: i18n.global.t('input.editor.sideBySide'),
- icon: '',
- },
- {
- name: 'guide',
- action() {
- window.open('https://www.markdownguide.org/basic-syntax/', '_blank')
- },
- title: i18n.global.t('input.editor.guide'),
- icon: '',
- },
- ],
- }
-}
\ No newline at end of file
diff --git a/src/components/input/vue-easymde.vue b/src/components/input/vue-easymde.vue
deleted file mode 100644
index 208c3da5..00000000
--- a/src/components/input/vue-easymde.vue
+++ /dev/null
@@ -1,522 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/misc/Icon.ts b/src/components/misc/Icon.ts
index b3ea6bdc..d50e3953 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, faArrowTurnDown, faListCheck, faXmark, faXmarksLines, faFont, faRulerHorizontal, faUnderline,
} 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)
@@ -146,6 +179,13 @@ library.add(faArrowUpFromBracket)
library.add(faX)
library.add(faAnglesUp)
library.add(faBolt)
+library.add(faArrowTurnDown)
+library.add(faListCheck)
+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
diff --git a/src/components/tasks/partials/comments.vue b/src/components/tasks/partials/comments.vue
index 95814a96..3af15654 100644
--- a/src/components/tasks/partials/comments.vue
+++ b/src/components/tasks/partials/comments.vue
@@ -66,7 +66,6 @@
@@ -114,12 +114,12 @@
taskCommentService.loading &&
!isCommentEdit,
}"
- :hasPreview="false"
:upload-callback="attachmentUpload"
:upload-enabled="true"
:placeholder="$t('task.comment.placeholder')"
v-if="editorActive"
v-model="newComment.comment"
+ @save="addComment()"
/>
diff --git a/src/components/tasks/partials/description.vue b/src/components/tasks/partials/description.vue
index c1ceedcb..12014461 100644
--- a/src/components/tasks/partials/description.vue
+++ b/src/components/tasks/partials/description.vue
@@ -18,21 +18,20 @@
diff --git a/src/helpers/checklistFromText.test.ts b/src/helpers/checklistFromText.test.ts
index 6b0fd54a..f01b712b 100644
--- a/src/helpers/checklistFromText.test.ts
+++ b/src/helpers/checklistFromText.test.ts
@@ -10,48 +10,56 @@ describe('Find checklists in text', () => {
expect(checkboxes).toHaveLength(0)
})
it('should find multiple checkboxes', () => {
- const text: string = `* [ ] Lorem Ipsum
-* [ ] Dolor sit amet
-
-Here's some text in between
-
-* [x] Dolor sit amet
-- [ ] Dolor sit amet`
+ const text: string = `
+`
const checkboxes = findCheckboxesInText(text)
expect(checkboxes).toHaveLength(4)
- expect(checkboxes[0]).toBe(0)
- expect(checkboxes[1]).toBe(18)
- expect(checkboxes[2]).toBe(69)
- expect(checkboxes[3]).toBe(90)
+ expect(checkboxes[0]).toBe(32)
+ expect(checkboxes[1]).toBe(163)
+ expect(checkboxes[2]).toBe(321)
+ expect(checkboxes[3]).toBe(464)
})
- it('should find one checkbox with *', () => {
- const text: string = '* [ ] Lorem Ipsum'
+ it('should find one unchecked checkbox', () => {
+ const text: string = `
+`
const checkboxes = findCheckboxesInText(text)
expect(checkboxes).toHaveLength(1)
- expect(checkboxes[0]).toBe(0)
+ expect(checkboxes[0]).toBe(32)
})
- it('should find one checkbox with -', () => {
- const text: string = '- [ ] Lorem Ipsum'
+ it('should find one checked checkbox', () => {
+ const text: string = `
+`
const checkboxes = findCheckboxesInText(text)
expect(checkboxes).toHaveLength(1)
- expect(checkboxes[0]).toBe(0)
- })
- it('should find one checked checkbox with *', () => {
- const text: string = '* [x] Lorem Ipsum'
- const checkboxes = findCheckboxesInText(text)
-
- expect(checkboxes).toHaveLength(1)
- expect(checkboxes[0]).toBe(0)
- })
- it('should find one checked checkbox with -', () => {
- const text: string = '- [x] Lorem Ipsum'
- const checkboxes = findCheckboxesInText(text)
-
- expect(checkboxes).toHaveLength(1)
- expect(checkboxes[0]).toBe(0)
+ expect(checkboxes[0]).toBe(32)
})
})
@@ -63,32 +71,60 @@ describe('Get Checklist Statistics in a Text', () => {
expect(stats.total).toBe(0)
})
it('should find one checkbox', () => {
- const text: string = '* [ ] Lorem Ipsum'
+ const text: string = `
+`
const stats = getChecklistStatistics(text)
expect(stats.total).toBe(1)
expect(stats.checked).toBe(0)
})
it('should find one checked checkbox', () => {
- const text: string = '* [x] Lorem Ipsum'
+ const text: string = `
+`
const stats = getChecklistStatistics(text)
expect(stats.total).toBe(1)
expect(stats.checked).toBe(1)
})
it('should find multiple mixed and matched', () => {
- const text: string = `* [ ] Lorem Ipsum
-* [ ] Dolor sit amet
-* [x] Dolor sit amet
-- [x] Dolor sit amet
+ const text: string = `
+`
-Here's some text in between
-
-* [x] Dolor sit amet
-- [ ] Dolor sit amet`
const stats = getChecklistStatistics(text)
expect(stats.total).toBe(6)
- expect(stats.checked).toBe(3)
+ expect(stats.checked).toBe(2)
})
})
diff --git a/src/helpers/checklistFromText.ts b/src/helpers/checklistFromText.ts
index 65294842..162b94a3 100644
--- a/src/helpers/checklistFromText.ts
+++ b/src/helpers/checklistFromText.ts
@@ -1,5 +1,3 @@
-const checked = '[x]'
-
interface CheckboxStatistics {
total: number
checked: number
@@ -11,7 +9,7 @@ interface MatchedCheckboxes {
}
const getCheckboxesInText = (text: string): MatchedCheckboxes => {
- const regex = /[*-] \[[ x]]/g
+ const regex = /data-checked="(true|false)"/g
let match
const checkboxes: MatchedCheckboxes = {
checked: [],
@@ -19,7 +17,7 @@ const getCheckboxesInText = (text: string): MatchedCheckboxes => {
}
while ((match = regex.exec(text)) !== null) {
- if (match[0].endsWith(checked)) {
+ if (match[1] === 'true') {
checkboxes.checked.push(match.index)
} else {
checkboxes.unchecked.push(match.index)
diff --git a/src/helpers/markdownRenderer.ts b/src/helpers/markdownRenderer.ts
deleted file mode 100644
index 2c399353..00000000
--- a/src/helpers/markdownRenderer.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import {marked} from 'marked'
-import hljs from 'highlight.js/lib/common'
-
-export function setupMarkdownRenderer(checkboxId: string) {
- const renderer = new marked.Renderer()
- const linkRenderer = renderer.link
-
- let checkboxNum = -1
- marked.use({
- renderer: {
- image(src: string, title: string, text: string) {
-
- title = title ? ` title="${title}` : ''
-
- // If the url starts with the api url, the image is likely an attachment and
- // we'll need to download and parse it properly.
- if (src.slice(0, window.API_URL.length + 7) === `${window.API_URL}/tasks/`) {
- return ``
- }
-
- return ``
- },
- checkbox(checked: boolean) {
- let checkedString = ''
- if (checked) {
- checkedString = 'checked'
- }
-
- checkboxNum++
- return ``
- },
- link(href: string, title: string, text: string) {
- const isLocal = href.startsWith(`${location.protocol}//${location.hostname}`)
- const html = linkRenderer.call(renderer, href, title, text)
- return isLocal ? html : html.replace(/^
diff --git a/src/views/labels/ListLabels.vue b/src/views/labels/ListLabels.vue
index 56b083ce..111476d1 100644
--- a/src/views/labels/ListLabels.vue
+++ b/src/views/labels/ListLabels.vue
@@ -58,7 +58,6 @@
import {computed} from 'vue'
-import {setupMarkdownRenderer} from '@/helpers/markdownRenderer'
-import {marked} from 'marked'
import DOMPurify from 'dompurify'
-import {createRandomID} from '@/helpers/randomId'
import {useProjectStore} from '@/stores/projects'
const props = defineProps({
@@ -36,7 +33,6 @@ const htmlDescription = computed(() => {
return ''
}
- setupMarkdownRenderer(createRandomID())
- return DOMPurify.sanitize(marked(description), {ADD_ATTR: ['target']})
+ return DOMPurify.sanitize(description, {ADD_ATTR: ['target']})
})
diff --git a/src/views/project/settings/edit.vue b/src/views/project/settings/edit.vue
index 46c8916b..595e1d96 100644
--- a/src/views/project/settings/edit.vue
+++ b/src/views/project/settings/edit.vue
@@ -54,7 +54,6 @@