From 220359b1c9b01ac1c499395b0a69cd46d68b87c5 Mon Sep 17 00:00:00 2001 From: Davide Silvestri <davide@baserow.io> Date: Thu, 22 Feb 2024 12:27:49 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9A1=EF=B8=8F=E2=83=A3=20Rich=20text:?= =?UTF-8?q?=20Grid=20view=20and=20Row=20edit=20modal=20editor=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contrib/database/fields/field_types.py | 2 + .../baserow/contrib/database/fields/models.py | 4 +- ...ngtextfield_enable_rich_text_formatting.py | 21 ++ .../scss/components/rich_text_editor.scss | 32 +- .../components/row_comments/RowComment.vue | 4 +- .../RowCommentMentionNotification.vue | 6 +- .../row_comments/RowCommentNotification.vue | 6 +- .../row_comments/RowCommentsSidebar.vue | 5 +- web-frontend/config/nuxt.config.base.js | 7 +- .../core/assets/scss/components/all.scss | 1 + .../scss/components/fields/rich_text.scss | 13 + .../scss/components/views/grid/long_text.scss | 27 ++ .../core/components/editor/RichTextEditor.vue | 224 +++++++++---- .../components/field/FieldLongTextSubForm.vue | 35 ++ .../components/row/RowEditFieldRichText.vue | 44 +++ .../components/view/grid/GridViewCell.vue | 2 +- .../view/grid/fields/GridViewFieldFormula.vue | 2 +- .../grid/fields/GridViewFieldRichText.vue | 64 ++++ web-frontend/modules/database/fieldTypes.js | 25 +- web-frontend/modules/database/locales/en.json | 3 + web-frontend/package.json | 37 +- web-frontend/yarn.lock | 317 +++++++++++++----- 22 files changed, 705 insertions(+), 176 deletions(-) create mode 100644 backend/src/baserow/contrib/database/migrations/0152_longtextfield_enable_rich_text_formatting.py create mode 100644 web-frontend/modules/core/assets/scss/components/fields/rich_text.scss create mode 100644 web-frontend/modules/database/components/field/FieldLongTextSubForm.vue create mode 100644 web-frontend/modules/database/components/row/RowEditFieldRichText.vue create mode 100644 web-frontend/modules/database/components/view/grid/fields/GridViewFieldRichText.vue diff --git a/backend/src/baserow/contrib/database/fields/field_types.py b/backend/src/baserow/contrib/database/fields/field_types.py index e6a713ba3..011242a15 100755 --- a/backend/src/baserow/contrib/database/fields/field_types.py +++ b/backend/src/baserow/contrib/database/fields/field_types.py @@ -402,6 +402,8 @@ class TextFieldType(CollationSortMixin, FieldType): class LongTextFieldType(CollationSortMixin, FieldType): type = "long_text" model_class = LongTextField + allowed_fields = ["long_text_enable_rich_text"] + serializer_field_names = ["long_text_enable_rich_text"] _can_group_by = True def get_serializer_field(self, instance, **kwargs): diff --git a/backend/src/baserow/contrib/database/fields/models.py b/backend/src/baserow/contrib/database/fields/models.py index e512815bc..e84ccc877 100644 --- a/backend/src/baserow/contrib/database/fields/models.py +++ b/backend/src/baserow/contrib/database/fields/models.py @@ -257,7 +257,9 @@ class TextField(Field): class LongTextField(Field): - pass + long_text_enable_rich_text = models.BooleanField( + default=False, null=True, help_text="Enable rich text formatting for the field." + ) # TODO: Remove null=True in a future release. class URLField(Field): diff --git a/backend/src/baserow/contrib/database/migrations/0152_longtextfield_enable_rich_text_formatting.py b/backend/src/baserow/contrib/database/migrations/0152_longtextfield_enable_rich_text_formatting.py new file mode 100644 index 000000000..75539ceed --- /dev/null +++ b/backend/src/baserow/contrib/database/migrations/0152_longtextfield_enable_rich_text_formatting.py @@ -0,0 +1,21 @@ +# Generated by Django 4.1.13 on 2024-02-09 15:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("database", "0151_tableusageupdate_tableusage"), + ] + + operations = [ + migrations.AddField( + model_name="longtextfield", + name="long_text_enable_rich_text", + field=models.BooleanField( + default=False, + help_text="Enable rich text formatting for the field.", + null=True, + ), + ), + ] diff --git a/premium/web-frontend/modules/baserow_premium/assets/scss/components/rich_text_editor.scss b/premium/web-frontend/modules/baserow_premium/assets/scss/components/rich_text_editor.scss index 553e35563..bbd667f5c 100644 --- a/premium/web-frontend/modules/baserow_premium/assets/scss/components/rich_text_editor.scss +++ b/premium/web-frontend/modules/baserow_premium/assets/scss/components/rich_text_editor.scss @@ -1,13 +1,39 @@ .rich-text-editor { width: 100%; - background-color: white; - max-height: 60vh; - overflow-y: auto; + height: 100%; text-align: left; + .tiptap.ProseMirror { + height: 100%; + } + p { + margin: 0; color: revert; } + + ul { + list-style-type: disc; + } + + blockquote { + margin: 1rem; + padding-left: 1rem; + color: $color-neutral-700; + border-left: 4px solid $color-neutral-300; + } + + pre { + padding: 1rem; + background-color: $color-neutral-100; + border-radius: $rounded; + } +} + +.rich-text-editor__comment { + max-height: 60vh; + overflow-y: auto; + background-color: white; } .rich-text-editor__mention { diff --git a/premium/web-frontend/modules/baserow_premium/components/row_comments/RowComment.vue b/premium/web-frontend/modules/baserow_premium/components/row_comments/RowComment.vue index d645c0c1a..f1acb48da 100644 --- a/premium/web-frontend/modules/baserow_premium/components/row_comments/RowComment.vue +++ b/premium/web-frontend/modules/baserow_premium/components/row_comments/RowComment.vue @@ -60,7 +60,9 @@ ref="editor" v-model="message" :editable="editing" - @entered="stopEdit(true)" + :enable-mentions="true" + :enter-stop-edit="true" + @stop-edit="stopEdit(true)" /> </div> <div v-if="editing" class="row_comments__comment-text-actions"> diff --git a/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentMentionNotification.vue b/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentMentionNotification.vue index d691f4989..b0cf19bcd 100644 --- a/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentMentionNotification.vue +++ b/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentMentionNotification.vue @@ -24,7 +24,11 @@ </template> </i18n> </div> - <RichTextEditor :editable="false" :value="notification.data.message" /> + <RichTextEditor + :editable="false" + :enable-mentions="true" + :value="notification.data.message" + /> </nuxt-link> </template> diff --git a/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentNotification.vue b/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentNotification.vue index 4cc88006f..2e2363e01 100644 --- a/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentNotification.vue +++ b/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentNotification.vue @@ -22,7 +22,11 @@ </template> </i18n> </div> - <RichTextEditor :editable="false" :value="notification.data.message" /> + <RichTextEditor + :editable="false" + :enable-mentions="true" + :value="notification.data.message" + /> </nuxt-link> </template> diff --git a/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentsSidebar.vue b/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentsSidebar.vue index ba6a0b79f..49f9d05b9 100644 --- a/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentsSidebar.vue +++ b/premium/web-frontend/modules/baserow_premium/components/row_comments/RowCommentsSidebar.vue @@ -85,8 +85,11 @@ > <RichTextEditor v-model="comment" + editor-class="rich-text-editor__comment" + :enable-mentions="true" :placeholder="$t('rowCommentSidebar.comment')" - @entered="postComment()" + :enter-stop-edit="true" + @stop-edit="postComment()" /> </div> </div> diff --git a/web-frontend/config/nuxt.config.base.js b/web-frontend/config/nuxt.config.base.js index bd70fdca5..753abf3e1 100644 --- a/web-frontend/config/nuxt.config.base.js +++ b/web-frontend/config/nuxt.config.base.js @@ -48,9 +48,14 @@ export default function ( build: { extend(config, ctx) { config.node = { fs: 'empty' } + config.module.rules.push({ + test: /\.(m|c)js$/, + include: /node_modules/, + type: 'javascript/auto', + }) }, babel: { compact: true }, - transpile: ['axios'], + transpile: ['axios', 'tiptap-markdown'], }, } } diff --git a/web-frontend/modules/core/assets/scss/components/all.scss b/web-frontend/modules/core/assets/scss/components/all.scss index a00836251..c8b95ac63 100644 --- a/web-frontend/modules/core/assets/scss/components/all.scss +++ b/web-frontend/modules/core/assets/scss/components/all.scss @@ -25,6 +25,7 @@ @import 'fields/number'; @import 'fields/rating'; @import 'fields/long_text'; +@import 'fields/rich_text'; @import 'fields/date'; @import 'fields/link_row'; @import 'fields/file'; diff --git a/web-frontend/modules/core/assets/scss/components/fields/rich_text.scss b/web-frontend/modules/core/assets/scss/components/fields/rich_text.scss new file mode 100644 index 000000000..40d738161 --- /dev/null +++ b/web-frontend/modules/core/assets/scss/components/fields/rich_text.scss @@ -0,0 +1,13 @@ +.field-rich-text { + @extend .field-long-text; + + overflow-y: auto; + + &.active { + border-color: $palette-blue-500; + } + + & .rich-text-editor[conteteditable='false'] { + background-color: $palette-neutral-700; + } +} diff --git a/web-frontend/modules/core/assets/scss/components/views/grid/long_text.scss b/web-frontend/modules/core/assets/scss/components/views/grid/long_text.scss index 1c1b6b78c..9fe1010b6 100644 --- a/web-frontend/modules/core/assets/scss/components/views/grid/long_text.scss +++ b/web-frontend/modules/core/assets/scss/components/views/grid/long_text.scss @@ -32,3 +32,30 @@ background-color: $color-primary-100; } } + +.grid-field-long-text--uniform { + & h1, + h2, + h3, + p, + a, + ul, + ol, + li, + blockquote, + pre, + code { + @extend %ellipsis; + + @include fixed-height(32px, 13px); + + padding: 0; + margin-top: 0; + margin-bottom: 0; + color: revert; + } + + li::marker { + content: initial; + } +} diff --git a/web-frontend/modules/core/components/editor/RichTextEditor.vue b/web-frontend/modules/core/components/editor/RichTextEditor.vue index 119f227af..73be2a127 100644 --- a/web-frontend/modules/core/components/editor/RichTextEditor.vue +++ b/web-frontend/modules/core/components/editor/RichTextEditor.vue @@ -1,11 +1,16 @@ <template> <div> <RichTextEditorMentionsList + v-if="editable && enableMentions" ref="mentionsList" :show-search="false" :add-empty-item="false" /> - <EditorContent :editor="editor" /> + <EditorContent + class="rich-text-editor" + :class="[editorClass]" + :editor="editor" + /> </div> </template> @@ -18,22 +23,62 @@ import { Mention } from '@tiptap/extension-mention' import { Document } from '@tiptap/extension-document' import { Paragraph } from '@tiptap/extension-paragraph' import { HardBreak } from '@tiptap/extension-hard-break' +import { Heading } from '@tiptap/extension-heading' +import { ListItem } from '@tiptap/extension-list-item' +import { BulletList } from '@tiptap/extension-bullet-list' +import { OrderedList } from '@tiptap/extension-ordered-list' +import { Bold } from '@tiptap/extension-bold' +import { Italic } from '@tiptap/extension-italic' +import { Strike } from '@tiptap/extension-strike' +import { Underline } from '@tiptap/extension-underline' +import { Subscript } from '@tiptap/extension-subscript' +import { Superscript } from '@tiptap/extension-superscript' +import { Blockquote } from '@tiptap/extension-blockquote' +import { CodeBlock } from '@tiptap/extension-code-block' +import { HorizontalRule } from '@tiptap/extension-horizontal-rule' import { Text } from '@tiptap/extension-text' import { Extension, mergeAttributes } from '@tiptap/core' import { Plugin, PluginKey } from '@tiptap/pm/state' +import { Markdown } from 'tiptap-markdown' import RichTextEditorMentionsList from '@baserow/modules/core/components/editor/RichTextEditorMentionsList' import suggestion from '@baserow/modules/core/editor/suggestion' +const richTextEditorExtensions = [ + // Nodes + Heading.configure({ levels: [1, 2, 3] }), + ListItem, + OrderedList, + BulletList, + CodeBlock, + Blockquote, + HorizontalRule, + // Marks + Bold, + Italic, + Strike, + Underline, + Subscript, + Superscript, + // Extensions + Markdown, +] + // Please, note that we need to remap Enter to Shift-Enter for every extension // relying on it in order to emit an event when the user presses Enter. -const EnterKeyExtension = Extension.create({ - name: 'enterKeyEventHandler', +const EnterStopEditExtension = Extension.create({ + name: 'enterStopEditHandler', + + addOptions() { + return { + shiftKey: false, + } + }, addProseMirrorPlugins() { return [ new Plugin({ - key: new PluginKey('enterKeyEventHandler'), + key: new PluginKey('enterStopEditHandler'), props: { handleKeyDown: (view, event) => { const { doc } = view.state @@ -41,17 +86,23 @@ const EnterKeyExtension = Extension.create({ function isDocEmpty() { let isEmpty = true doc.descendants((node) => { - const textNodes = ['text', 'paragraph', 'hardBreak'] - if (!textNodes.includes(node.type.name) || node.text?.trim()) { + const isContent = + node.type.name !== 'hardBreak' && + !node.isText && + !node.isBlock + if (isContent || node.text?.trim()) { isEmpty = false } }) return isEmpty } - if (event.key === 'Enter' && !event.shiftKey) { + if ( + event.key === 'Enter' && + event.shiftKey === this.options.shiftKey + ) { if (!isDocEmpty()) { - this.options.vueComponent.$emit('entered') + this.options.vueComponent.$emit('stop-edit') } return true } @@ -81,6 +132,26 @@ export default { type: Boolean, default: true, }, + editorClass: { + type: String, + default: '', + }, + enableMentions: { + type: Boolean, + default: false, + }, + enterStopEdit: { + type: Boolean, + default: false, + }, + shiftEnterStopEdit: { + type: Boolean, + default: false, + }, + enableRichTextFormatting: { + type: Boolean, + default: false, + }, }, data() { return { @@ -91,8 +162,6 @@ export default { ...mapGetters({ loggedUserId: 'auth/getUserId', workspace: 'workspace/getSelected', - isUserIdMemberOfSelectedWorkspace: - 'workspace/isUserIdMemberOfSelectedWorkspace', }), }, watch: { @@ -103,70 +172,97 @@ export default { this.editor.commands.focus('end') }, value(value) { - const jsonContent = this.editor.getJSON() - - if (_.isEqual(jsonContent, value)) { - return + if (!_.isEqual(value, this.editor.getJSON())) { + this.editor.commands.setContent(value, false) } - - this.editor.commands.setContent(value, false) }, }, mounted() { - const loggedUserId = this.loggedUserId - const originalRenderHTML = Mention.config.renderHTML - const isUserInWorkspace = - this.$store.getters['workspace/isUserIdMemberOfSelectedWorkspace'] - const mentionsExt = Mention.extend({ - renderHTML({ node, HTMLAttributes }) { + const extensions = this.getConfiguredExtensions() + this.initTiptapEditor(extensions) + }, + unmounted() { + this.editor.destroy() + }, + methods: { + getConfiguredExtensions() { + const extensions = [Document, Paragraph, Text, HardBreak] + + if (this.enableRichTextFormatting) { + extensions.push(...richTextEditorExtensions) + } + + if (this.enterStopEdit || this.shiftEnterStopEdit) { + const enterKeyExt = EnterStopEditExtension.configure({ + vueComponent: this, + shiftKey: this.shiftEnterStopEdit, + }) + extensions.push(enterKeyExt) + } + if (this.enableMentions) { + const renderHTML = this.customRenderHTMLForMentions() + const mentionsExt = Mention.configure({ + renderHTML, + suggestion: suggestion({ + component: this.$refs.mentionsList, + }), + }) + extensions.push(mentionsExt) + } + + if (this.placeholder) { + extensions.push( + Placeholder.configure({ + placeholder: this.placeholder, + }) + ) + } + return extensions + }, + initTiptapEditor(extensions) { + this.editor = new Editor({ + content: this.value, + editable: this.editable, + extensions, + onUpdate: () => { + this.$emit('input', this.editor.getJSON()) + }, + onFocus: () => { + this.$emit('focus') + }, + onBlur: () => { + this.$emit('blur') + }, + }) + + if (this.editable && this.enableRichTextFormatting) { + this.editor.commands.unsetAllMarks() + } + }, + customRenderHTMLForMentions() { + const loggedUserId = this.loggedUserId + const isUserInWorkspace = + this.$store.getters['workspace/isUserIdMemberOfSelectedWorkspace'] + return ({ node, options }) => { let className = 'rich-text-editor__mention' if (node.attrs.id === loggedUserId) { className += ' rich-text-editor__mention--current-user' } else if (!isUserInWorkspace(node.attrs.id)) { className += ' rich-text-editor__mention--user-gone' } - return originalRenderHTML.call(this, { - node, - HTMLAttributes: mergeAttributes(HTMLAttributes, { class: className }), - }) - }, - }).configure({ - suggestion: suggestion({ - component: this.$refs.mentionsList, - }), - }) - const enterKeyExt = EnterKeyExtension.configure({ vueComponent: this }) - const extensions = [ - Document, - Paragraph, - Text, - HardBreak, - enterKeyExt, - mentionsExt, - ] - if (this.placeholder) { - extensions.push( - Placeholder.configure({ - placeholder: this.placeholder, - }) - ) - } - this.editor = new Editor({ - content: this.value, - editable: this.editable, - editorProps: { - attributes: { - class: this.editable ? 'rich-text-editor' : null, - }, - }, - extensions, - onUpdate: () => { - this.$emit('input', this.editor.getJSON()) - }, - }) - }, - beforeDestroy() { - this.editor.destroy() + return [ + 'span', + mergeAttributes({ class: className }, this.HTMLAttributes), + `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`, + ] + } + }, + focus() { + this.editor.commands.focus('end') + }, + serializeToMarkdown() { + return this.editor.storage.markdown.getMarkdown() + }, }, } </script> diff --git a/web-frontend/modules/database/components/field/FieldLongTextSubForm.vue b/web-frontend/modules/database/components/field/FieldLongTextSubForm.vue new file mode 100644 index 000000000..78c39473d --- /dev/null +++ b/web-frontend/modules/database/components/field/FieldLongTextSubForm.vue @@ -0,0 +1,35 @@ +<template> + <div> + <div v-if="$featureFlagIsEnabled('rich-text-field')" class="control"> + <div class="control__elements"> + <Checkbox v-model="values.long_text_enable_rich_text">{{ + $t('fieldLongTextSubForm.enableRichTextFormatting') + }}</Checkbox> + </div> + </div> + </div> +</template> + +<script> +import form from '@baserow/modules/core/mixins/form' + +import fieldSubForm from '@baserow/modules/database/mixins/fieldSubForm' + +export default { + name: 'FieldTextSubForm', + mixins: [form, fieldSubForm], + data() { + return { + allowedValues: ['long_text_enable_rich_text'], + values: { + long_text_enable_rich_text: false, + }, + } + }, + methods: { + isFormValid() { + return true + }, + }, +} +</script> diff --git a/web-frontend/modules/database/components/row/RowEditFieldRichText.vue b/web-frontend/modules/database/components/row/RowEditFieldRichText.vue new file mode 100644 index 000000000..118be7741 --- /dev/null +++ b/web-frontend/modules/database/components/row/RowEditFieldRichText.vue @@ -0,0 +1,44 @@ +<template> + <div class="control__elements"> + <RichTextEditor + ref="input" + v-model="richCopy" + class="input field-rich-text" + :class="{ 'input--error': touched && !valid, active: editing }" + :disabled="readOnly" + :editable="!readOnly" + :enable-rich-text-formatting="true" + @focus="select()" + @blur="unselect()" + ></RichTextEditor> + + <div v-show="touched && !valid" class="error"> + {{ error }} + </div> + </div> +</template> + +<script> +import RichTextEditor from '@baserow/modules/core/components/editor/RichTextEditor.vue' +import rowEditField from '@baserow/modules/database/mixins/rowEditField' +import rowEditFieldInput from '@baserow/modules/database/mixins/rowEditFieldInput' + +export default { + components: { RichTextEditor }, + mixins: [rowEditField, rowEditFieldInput], + data() { + return { + // local copy of the value storing the JSON representation of the rich text editor + richCopy: '', + } + }, + created() { + this.richCopy = this.value || '' + }, + methods: { + beforeSave() { + return this.$refs.input.serializeToMarkdown() + }, + }, +} +</script> diff --git a/web-frontend/modules/database/components/view/grid/GridViewCell.vue b/web-frontend/modules/database/components/view/grid/GridViewCell.vue index 3e1ea2f41..da5818810 100644 --- a/web-frontend/modules/database/components/view/grid/GridViewCell.vue +++ b/web-frontend/modules/database/components/view/grid/GridViewCell.vue @@ -102,7 +102,7 @@ export default { getComponent(parent, props) { return parent.$registry .get('field', props.field.type) - .getGridViewFieldComponent() + .getGridViewFieldComponent(props.field) }, /** * If the grid field component emits an update event then this method will be diff --git a/web-frontend/modules/database/components/view/grid/fields/GridViewFieldFormula.vue b/web-frontend/modules/database/components/view/grid/fields/GridViewFieldFormula.vue index bb8d7c8f0..d6596bd13 100644 --- a/web-frontend/modules/database/components/view/grid/fields/GridViewFieldFormula.vue +++ b/web-frontend/modules/database/components/view/grid/fields/GridViewFieldFormula.vue @@ -15,7 +15,7 @@ export default { getComponent(field, registry) { return registry .get('formula_type', field.formula_type) - .getGridViewFieldComponent() + .getGridViewFieldComponent(field) }, }, } diff --git a/web-frontend/modules/database/components/view/grid/fields/GridViewFieldRichText.vue b/web-frontend/modules/database/components/view/grid/fields/GridViewFieldRichText.vue new file mode 100644 index 000000000..6549d13fe --- /dev/null +++ b/web-frontend/modules/database/components/view/grid/fields/GridViewFieldRichText.vue @@ -0,0 +1,64 @@ +<template> + <div + ref="cell" + class="grid-view__cell grid-field-long-text__cell active" + :class="{ editing: opened }" + @contextmenu="stopContextIfEditing($event)" + > + <div v-if="!opened" class="grid-field-long-text"> + {{ value }} + </div> + <div + v-else-if="editing" + v-prevent-parent-scroll + class="grid-field-long-text__textarea" + > + <RichTextEditor + ref="input" + v-model="richCopy" + :enable-rich-text-formatting="true" + ></RichTextEditor> + </div> + <div v-else class="grid-field-long-text__textarea"> + {{ richCopy }} + </div> + </div> +</template> + +<script> +import RichTextEditor from '@baserow/modules/core/components/editor/RichTextEditor.vue' +import gridField from '@baserow/modules/database/mixins/gridField' +import gridFieldInput from '@baserow/modules/database/mixins/gridFieldInput' + +export default { + components: { RichTextEditor }, + mixins: [gridField, gridFieldInput], + data() { + return { + // local copy of the value storing the JSON representation of the rich text editor + richCopy: '', + } + }, + watch: { + value: { + handler(value) { + this.richCopy = value || '' + }, + immediate: true, + }, + }, + methods: { + beforeSave() { + return this.$refs.input.serializeToMarkdown() + }, + afterEdit() { + this.$nextTick(() => { + this.$refs.input.focus() + }) + }, + canSaveByPressingEnter(event) { + return false + }, + }, +} +</script> diff --git a/web-frontend/modules/database/fieldTypes.js b/web-frontend/modules/database/fieldTypes.js index 8f6a4d250..7ee5addaa 100644 --- a/web-frontend/modules/database/fieldTypes.js +++ b/web-frontend/modules/database/fieldTypes.js @@ -24,6 +24,7 @@ import FieldAutonumberSubForm from '@baserow/modules/database/components/field/F import FieldDurationSubForm from '@baserow/modules/database/components/field/FieldDurationSubForm' import FieldRatingSubForm from '@baserow/modules/database/components/field/FieldRatingSubForm' import FieldTextSubForm from '@baserow/modules/database/components/field/FieldTextSubForm' +import FieldLongTextSubForm from '@baserow/modules/database/components/field/FieldLongTextSubForm' import FieldDateSubForm from '@baserow/modules/database/components/field/FieldDateSubForm' import FieldLinkRowSubForm from '@baserow/modules/database/components/field/FieldLinkRowSubForm' import FieldSelectOptionsSubForm from '@baserow/modules/database/components/field/FieldSelectOptionsSubForm' @@ -31,6 +32,7 @@ import FieldCollaboratorSubForm from '@baserow/modules/database/components/field import GridViewFieldText from '@baserow/modules/database/components/view/grid/fields/GridViewFieldText' import GridViewFieldLongText from '@baserow/modules/database/components/view/grid/fields/GridViewFieldLongText' +import GridViewFieldRichText from '@baserow/modules/database/components/view/grid/fields/GridViewFieldRichText' import GridViewFieldURL from '@baserow/modules/database/components/view/grid/fields/GridViewFieldURL' import GridViewFieldEmail from '@baserow/modules/database/components/view/grid/fields/GridViewFieldEmail' import GridViewFieldLinkRow from '@baserow/modules/database/components/view/grid/fields/GridViewFieldLinkRow' @@ -69,6 +71,7 @@ import FunctionalGridViewFieldLastModifiedBy from '@baserow/modules/database/com import RowEditFieldText from '@baserow/modules/database/components/row/RowEditFieldText' import RowEditFieldLongText from '@baserow/modules/database/components/row/RowEditFieldLongText' +import RowEditFieldRichText from '@baserow/modules/database/components/row/RowEditFieldRichText' import RowEditFieldURL from '@baserow/modules/database/components/row/RowEditFieldURL' import RowEditFieldEmail from '@baserow/modules/database/components/row/RowEditFieldEmail' import RowEditFieldLinkRow from '@baserow/modules/database/components/row/RowEditFieldLinkRow' @@ -170,7 +173,7 @@ export class FieldType extends Registerable { * example if we are creating a number fields this component should contain * the inputs to choose of it is an integer of decimal. */ - getFormComponent() { + getFormComponent(field) { return null } @@ -179,7 +182,7 @@ export class FieldType extends Registerable { * type. It will only be used in the grid view and it also responsible for editing * the value. */ - getGridViewFieldComponent() { + getGridViewFieldComponent(field) { throw new Error( 'Not implement error. This method should return a component.' ) @@ -847,8 +850,16 @@ export class LongTextFieldType extends FieldType { return i18n.t('fieldType.longText') } - getGridViewFieldComponent() { - return GridViewFieldLongText + getFormComponent() { + return FieldLongTextSubForm + } + + getGridViewFieldComponent(field) { + if (field?.long_text_enable_rich_text) { + return GridViewFieldRichText + } else { + return GridViewFieldLongText + } } getFunctionalGridViewFieldComponent() { @@ -856,7 +867,11 @@ export class LongTextFieldType extends FieldType { } getRowEditFieldComponent(field) { - return RowEditFieldLongText + if (field?.long_text_enable_rich_text) { + return RowEditFieldRichText + } else { + return RowEditFieldLongText + } } getCardComponent() { diff --git a/web-frontend/modules/database/locales/en.json b/web-frontend/modules/database/locales/en.json index 12ea9a011..4227afdb5 100644 --- a/web-frontend/modules/database/locales/en.json +++ b/web-frontend/modules/database/locales/en.json @@ -425,6 +425,9 @@ "formulaInputPlaceholder": "Click to edit the formula", "refreshFormulaOptions": "Refresh formula options" }, + "fieldLongTextSubForm": { + "enableRichTextFormatting": "Enable rich text formatting" + }, "formulaFieldItemDescription": { "syntax": "Syntax", "examples": "Examples" diff --git a/web-frontend/package.json b/web-frontend/package.json index 24e4d454d..a9fd0058a 100644 --- a/web-frontend/package.json +++ b/web-frontend/package.json @@ -33,15 +33,31 @@ "@nuxtjs/sentry": "7.1.11", "@storybook/core-client": "6.5.9", "@tiptap/core": "^2.0.3", - "@tiptap/extension-document": "^2.0.3", - "@tiptap/extension-hard-break": "^2.0.3", - "@tiptap/extension-mention": "^2.0.3", - "@tiptap/extension-paragraph": "^2.0.3", - "@tiptap/extension-placeholder": "^2.0.3", - "@tiptap/extension-text": "^2.0.3", - "@tiptap/pm": "^2.0.3", - "@tiptap/suggestion": "^2.0.3", - "@tiptap/vue-2": "^2.0.3", + "@tiptap/extension-blockquote": "^2.2.2", + "@tiptap/extension-bold": "^2.2.2", + "@tiptap/extension-bullet-list": "^2.2.2", + "@tiptap/extension-code": "^2.2.2", + "@tiptap/extension-code-block": "^2.2.2", + "@tiptap/extension-document": "2.2.3", + "@tiptap/extension-hard-break": "2.2.3", + "@tiptap/extension-heading": "^2.0.3", + "@tiptap/extension-highlight": "^2.2.2", + "@tiptap/extension-horizontal-rule": "^2.2.2", + "@tiptap/extension-italic": "^2.2.2", + "@tiptap/extension-link": "^2.2.2", + "@tiptap/extension-list-item": "^2.2.2", + "@tiptap/extension-mention": "2.2.3", + "@tiptap/extension-ordered-list": "^2.2.2", + "@tiptap/extension-paragraph": "2.2.3", + "@tiptap/extension-placeholder": "2.2.3", + "@tiptap/extension-strike": "^2.2.3", + "@tiptap/extension-subscript": "^2.2.3", + "@tiptap/extension-superscript": "^2.2.3", + "@tiptap/extension-text": "2.2.3", + "@tiptap/extension-underline": "^2.2.3", + "@tiptap/pm": "2.2.3", + "@tiptap/suggestion": "2.2.3", + "@tiptap/vue-2": "2.2.3", "antlr4": "4.9.3", "async-mutex": "0.4.0", "axios": "^1.6.7", @@ -55,7 +71,7 @@ "jwt-decode": "^3.1.2", "lodash": "^4.17.21", "markdown-it": "13.0.1", - "moment": "2.29.4", + "moment": "^2.30.1", "moment-guess": "^1.2.4", "moment-timezone": "0.5.43", "node-sass": "8.0.0", @@ -67,6 +83,7 @@ "resize-observer-polyfill": "^1.5.1", "sass-loader": "10.4.1", "thenby": "^1.3.4", + "tiptap-markdown": "^0.8.9", "uuid": "9.0.0", "vue-chartjs": "4.1.2", "vuejs-datepicker": "1.6.2", diff --git a/web-frontend/yarn.lock b/web-frontend/yarn.lock index f46ec4acd..624b07e28 100644 --- a/web-frontend/yarn.lock +++ b/web-frontend/yarn.lock @@ -4263,86 +4263,168 @@ resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.1.13.tgz#e21f566e81688c826c6f26d2940886734189e193" integrity sha512-cMC8bgTN63dj1Mv82iDeeLl6sa9kY0Pug8LSalxVEptRmyFVsVxGgu2/6Y3T+9aCYScxfS06EkA8SdzFMAwYTQ== -"@tiptap/extension-bubble-menu@^2.1.13": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.1.13.tgz#884cd2e4e0c9586998baac3d0a14621b177f1859" - integrity sha512-Hm7e1GX3AI6lfaUmr6WqsS9MMyXIzCkhh+VQi6K8jj4Q4s8kY4KPoAyD/c3v9pZ/dieUtm2TfqrOCkbHzsJQBg== +"@tiptap/extension-blockquote@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.2.3.tgz#0951a321f56c70b3f276e11bd17fa1ff109042e7" + integrity sha512-gN23d/ADhTOB0YIM4lR0VrVczdyaXpmIVYYWZ45tQEVJzFWRSIScE9m9NaVqtqwEMpYHyTHxLth0OQutZ91sog== + +"@tiptap/extension-bold@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.2.3.tgz#e4cd91de4e8dbdabd915bbc10c86eda321e91d17" + integrity sha512-bHeFkRY5+Nf2DKupstV8EIVn359tw/9MFwDEDoF9F+Sn/vjuS35vm0OqjXYg/Ya9CQvwl/2oym/fKv5kO+Q6og== + +"@tiptap/extension-bubble-menu@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.2.3.tgz#e3b603324726aa2f96b2500855622ace625117df" + integrity sha512-6ybColxLznGilzOY/yk3KcpV4JQy+QDDW6Za6zWV6OEs9D8I8VUeMAS77isMMc1dffvHfmgZpVZm/lsva8UuCw== dependencies: tippy.js "^6.3.7" -"@tiptap/extension-document@^2.0.3": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.1.13.tgz#5b68fa08e8a79eebd41f1360982db2ddd28ad010" - integrity sha512-wLwiTWsVmZTGIE5duTcHRmW4ulVxNW4nmgfpk95+mPn1iKyNGtrVhGWleLhBlTj+DWXDtcfNWZgqZkZNzhkqYQ== +"@tiptap/extension-bullet-list@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.2.3.tgz#98b82afd9a6c553278d4b613b29dbed99da063f9" + integrity sha512-BpYg1pIfLE+2LTC90ts53deEWGSmAojhM/jJ84U19qfbfXt/7/KHrZJ4SAMxJSW3pLpy0bIq2XuOuvppOYVR5g== -"@tiptap/extension-floating-menu@^2.1.13": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.1.13.tgz#e12e6e73ee095319d4a723a9b46b8f7b1a9f4b1a" - integrity sha512-9Oz7pk1Nts2+EyY+rYfnREGbLzQ5UFazAvRhF6zAJdvyuDmAYm0Jp6s0GoTrpV0/dJEISoFaNpPdMJOb9EBNRw== +"@tiptap/extension-code-block@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.2.3.tgz#caeaad4f4ccf92963e73ddf1b90265edd94c7af3" + integrity sha512-1xFM2Aj/JEWAT1PWjQ/7hEVmo1Av6JHxTANxMIjXUcmrMJkXDA+BQ7yItlwrrHxY0SJdxBbR/WWFn4dWIxd7iA== + +"@tiptap/extension-code@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.2.3.tgz#183847b126496f9d4d473a72b7e1d2ab2a90da68" + integrity sha512-ZMp3CrbAV+PVOnPbGmruvlxFENLc+J/Fos8Y4mWvS1nDbrGuu19OKgKimwdzfDBpZVFVnHpEUnDTMBDzDe0hkg== + +"@tiptap/extension-document@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.2.3.tgz#40e4faac7369d0fea31ea4eb57716ed7393f24b7" + integrity sha512-60Egd9yKb5SzpQlstQAP2A/2a/Qr+A+TblMRKZugrT+NENUhAj6Tx1HxWlblqGu2MsS1iXvQLZ6BQO1jHkL2IQ== + +"@tiptap/extension-floating-menu@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.2.3.tgz#3e200f51760fd1d48cb572223dcaf54c70f244a6" + integrity sha512-ZeQGmIFNImhu/zzn//Xzupwa82j2vIwiMoviX2zd+2DutoFnm4qRIAU6qpjzV+ZOSHAq3aBMGnYwEAY6vl4f3g== dependencies: tippy.js "^6.3.7" -"@tiptap/extension-hard-break@^2.0.3": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.1.13.tgz#fc84d0ff7e2fe861bf421bc8000194ecc26979b0" - integrity sha512-TGkMzMQayuKg+vN4du0x1ahEItBLcCT1jdWeRsjdM8gHfzbPLdo4PQhVsvm1I0xaZmbJZelhnVsUwRZcIu1WNA== +"@tiptap/extension-hard-break@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.2.3.tgz#7d7b8e7bcf99be5f518a705c65ebcc1dacaaa514" + integrity sha512-P7sP4WBEaQyiiFAswy9lKvaUWUAUwnfTSN3svTAgx0fpU3/ZeVWg+SDi5ve474Ym2oz2eRAr09mNTdWEUsL32Q== -"@tiptap/extension-mention@^2.0.3": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/extension-mention/-/extension-mention-2.1.13.tgz#6359c563268c46539660958847fe76c22131f2c8" - integrity sha512-OYqaucyBiCN/CmDYjpOVX74RJcIEKmAqiZxUi8Gfaq7ryEO5a8Gk93nK+8uZ0onaqHE+mHpoLFFbcAFbOPgkUQ== +"@tiptap/extension-heading@^2.0.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.2.3.tgz#4934e3a887d8843f85706a809fd6293b2b42b2b5" + integrity sha512-7atctuvtwPqIAdnBPOhAMsJZd41UPnWN3CktzgzfsfEoplq/86QR1hGIE4JXVB2wAZDmbnKP9Fe8PCNr7Q8JCQ== -"@tiptap/extension-paragraph@^2.0.3": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.1.13.tgz#30f8ae3f8833c606b339f3554b9ffdbe1e604463" - integrity sha512-cEoZBJrsQn69FPpUMePXG/ltGXtqKISgypj70PEHXt5meKDjpmMVSY4/8cXvFYEYsI9GvIwyAK0OrfAHiSoROA== +"@tiptap/extension-highlight@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-highlight/-/extension-highlight-2.2.3.tgz#b9cf810547d2abc8b3b7567b9002397b6add3477" + integrity sha512-3K9WbrR2WCYq7a/2JSQi5K2zzG/5ebNfTOXyDcT3kn5B5PutyWuDCzqjkPxGXmkf8yEZTQ9Sn2lQPRMG3sNwFw== -"@tiptap/extension-placeholder@^2.0.3": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/extension-placeholder/-/extension-placeholder-2.1.13.tgz#b735591f719b9fe89c90dcc6327d2ef2851be510" - integrity sha512-vIY7y7UbqsrAW/y8bDE9eRenbQEU16kNHB5Wri8RU1YiUZpkPgdXP/pLqyjIIq95SwP/vdTIHjHoQ77VLRl1hA== +"@tiptap/extension-horizontal-rule@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.2.3.tgz#ff76b7627b6fea3ba5397fbfccd818f0f2e6efbd" + integrity sha512-pc0J0hBcvj9ymJkFau1W/3L+OhB1PQzMjsx4ZWJvxURL8U7zdDqvYvJjfCA0i5Qw2ZuSVXFACGbEVr6NoCMRAw== -"@tiptap/extension-text@^2.0.3": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.1.13.tgz#ac17a0220aef1bae1bbd646a91491353e57bb5d1" - integrity sha512-zzsTTvu5U67a8WjImi6DrmpX2Q/onLSaj+LRWPh36A1Pz2WaxW5asZgaS+xWCnR+UrozlCALWa01r7uv69jq0w== +"@tiptap/extension-italic@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.2.3.tgz#d01e075bf0db5ac01113a19ab80cc39af39033fc" + integrity sha512-SSsFuRnm4Y4Qnc6EuvmA4iarLCt/sg8qkqCKiNPjDUP5JR8HGESeoYVjQzprLHY8jusT9qoC26TP1Sin5vZmWQ== -"@tiptap/pm@^2.0.3": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.1.13.tgz#857753691580be760da13629fab2712c52750741" - integrity sha512-zNbA7muWsHuVg12GrTgN/j119rLePPq5M8dZgkKxUwdw8VmU3eUyBp1SihPEXJ2U0MGdZhNhFX7Y74g11u66sg== +"@tiptap/extension-link@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.2.3.tgz#5c6571dffebbe328277b0abfae0deccfb20c2559" + integrity sha512-AKKgkllpj0Po/hi2bVz719OMqyB1nBhKU/Q05yeWVirOYwF2ZwfM4iK2Iab7xWUVhvlyIG3lrWFQL8A30yuqwQ== dependencies: - prosemirror-changeset "^2.2.0" - prosemirror-collab "^1.3.0" - prosemirror-commands "^1.3.1" - prosemirror-dropcursor "^1.5.0" - prosemirror-gapcursor "^1.3.1" - prosemirror-history "^1.3.0" - prosemirror-inputrules "^1.2.0" - prosemirror-keymap "^1.2.0" - prosemirror-markdown "^1.10.1" - prosemirror-menu "^1.2.1" - prosemirror-model "^1.18.1" - prosemirror-schema-basic "^1.2.0" - prosemirror-schema-list "^1.2.2" - prosemirror-state "^1.4.1" - prosemirror-tables "^1.3.0" - prosemirror-trailing-node "^2.0.2" - prosemirror-transform "^1.7.0" - prosemirror-view "^1.28.2" + linkifyjs "^4.1.0" -"@tiptap/suggestion@^2.0.3": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.1.13.tgz#0a8317260baed764a523a09099c0889a0e5b507e" - integrity sha512-Y05TsiXTFAJ5SrfoV+21MAxig5UNbY0AVa03lQlh/yicTRPpIc6hgZzblB0uxDSYoj6+kaHE4MIZvPvhUD8BJQ== +"@tiptap/extension-list-item@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.2.3.tgz#dfdc268cc2063947dc46749464d6d91afc0842a4" + integrity sha512-eyfk4f1jOioj+mkIN2m6XQK61MpV0fi17utt8VNx893Td8kS0g7HHuuYMwyjIRtG35ENUaAt7c216JQwnLsrAw== -"@tiptap/vue-2@^2.0.3": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.1.13.tgz#e84c144fa36f79c36db3cf6913aef197002bd298" - integrity sha512-OsCINarPGyT3sDIXDrhVyaoH0I0VxeDDm+NgS5P0fPbBCnsHZ8csvxD9UB9/KZ/UoxYDfJ1zLplKQn1AIlnRzg== +"@tiptap/extension-mention@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-mention/-/extension-mention-2.2.3.tgz#3b43619b572db693a1e776d1269ceef2c9474192" + integrity sha512-HFSZcGLUJ/31aiOsc2CnkjS5EBg6EbU+SKLQZx7/pA4/ew4uSWOPI7a03mgGmNoRfR16est55OrauEuBj8hKrQ== + +"@tiptap/extension-ordered-list@^2.2.2": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.2.3.tgz#07588d9091076e0577f5e4873e2e65c27d69a7be" + integrity sha512-YIWpjkHAJN74tY185ZqatlG4+KbXQOdkJpc5cKWqO89gVWLi7+4xwdeeXbTEG64/LOOWS4Q6r1/EJmDy2FCbyA== + +"@tiptap/extension-paragraph@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.2.3.tgz#39e705198eba640a57f58276044950d3d77067ff" + integrity sha512-4dP+Ecb2iEWW33ckFKjXRnSfEygaFUN19qzc7mUYD8e61ZA8caWL6//uL7DFIz4Q1rchyefbU52gCwTh2P42kQ== + +"@tiptap/extension-placeholder@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-placeholder/-/extension-placeholder-2.2.3.tgz#d538bff70db199433a256fb37fac8e4058a3cfc1" + integrity sha512-Kc+9a/uACY9XBT0uB/qFVpIHm8MzVr0uWA7MCjwDcMneANRLsXEBzWBzyHxRFoNRECfocivV9hQIhuO4i09c9A== + +"@tiptap/extension-strike@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.2.3.tgz#9caaca60d4f717863b03a8ade71af22a1579096c" + integrity sha512-3wwFk01ociZajRzD08hp4j/4isFUeD6BIkKPDnZeGD5HKPdTOaDciE3dJ3JaZZrRZPPdPV3yMt5hkBOapqEKzQ== + +"@tiptap/extension-subscript@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.2.3.tgz#91c994222ea8120e0a19bd870cf47c8cfdc82353" + integrity sha512-zWN8MOfYSaGXNI5yKTk4I4hHSpCUz//NQASHD8OOKN+rt6i8RUTNynpJyCZC77RXdlvTY70Ox2vNgp/rriz+Qw== + +"@tiptap/extension-superscript@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.2.3.tgz#51cb2bde41656688ea6088e02d89d43195f6c1c6" + integrity sha512-4V4PoXPuxCiiISFxz1StP/5azQqUmlwCECJg8ketrQ6WFfUf54lzCEjMeo9RwwdBbfpL6dhwJ8mmv6qil4j1KA== + +"@tiptap/extension-text@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.2.3.tgz#3adc14b6f5956f2fb6102702beb0adbfe1f86131" + integrity sha512-BrWGCkmuzVcsNy7dSCfJyVwedPzeNz6BR/OUNzM8Mqt2KSxfoIRy7cg16HvFB4YW+ijrM9XUqDIFvqYI0TY+Jg== + +"@tiptap/extension-underline@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/extension-underline/-/extension-underline-2.2.3.tgz#ce77652d6d8d0a4337460be98910e5ff239ea41b" + integrity sha512-Y6PTaXmDFay39+Knk77T+Ezc5vuC/gFxZFD6cQhjctZHMJ2QMAguMKWtBVaSs78HBkKnwTU9EViAFBurz++Geg== + +"@tiptap/pm@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.2.3.tgz#88c8547015098ebd438211e839de64b043b655f3" + integrity sha512-jYZX+0fjN+a1J8qY72Poz1LK6X6oHVQkJIq6qzcx3rm0voYZNVRzP2GIfzstncZiEqRXABHY3mWfOi2I4K9tQA== dependencies: - "@tiptap/extension-bubble-menu" "^2.1.13" - "@tiptap/extension-floating-menu" "^2.1.13" + 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.3.0" + prosemirror-keymap "^1.2.2" + prosemirror-markdown "^1.12.0" + prosemirror-menu "^1.2.4" + prosemirror-model "^1.19.4" + prosemirror-schema-basic "^1.2.2" + prosemirror-schema-list "^1.3.0" + prosemirror-state "^1.4.3" + prosemirror-tables "^1.3.5" + prosemirror-trailing-node "^2.0.7" + prosemirror-transform "^1.8.0" + prosemirror-view "^1.32.7" + +"@tiptap/suggestion@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.2.3.tgz#d9286d53b0e37816628205a09035c344f6d46e7f" + integrity sha512-pMInbk8+rYNaCz4oT/uS498mxSGIJXU32mkXv7wdDqMT2nnZQ2AHtJDUtMuB1RX+DS4ll9vdzrKqQHSW5t2ybQ== + +"@tiptap/vue-2@2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.2.3.tgz#a1bee805e4b3df43a22d6738ed23d412127f6b5d" + integrity sha512-RWiqbD1UrWQMbClHO3fr7hQcKVzJaKs6MI9cWTJ9xktb3GiHqXVFm/WECgoUGo1MVliGs7v2NoSWQlh9PVcP3w== + dependencies: + "@tiptap/extension-bubble-menu" "^2.2.3" + "@tiptap/extension-floating-menu" "^2.2.3" vue-ts-types "^1.6.0" "@tootallnate/once@1": @@ -4542,11 +4624,24 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/linkify-it@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.5.tgz#1e78a3ac2428e6d7e6c05c1665c242023a4601d8" + integrity sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw== + "@types/lodash@^4.14.167": version "4.14.202" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== +"@types/markdown-it@^12.2.3": + version "12.2.3" + resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51" + integrity sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ== + dependencies: + "@types/linkify-it" "*" + "@types/mdurl" "*" + "@types/mdast@^3.0.0": version "3.0.15" resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5" @@ -4554,6 +4649,11 @@ dependencies: "@types/unist" "^2" +"@types/mdurl@*": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.5.tgz#3e0d2db570e9fb6ccb2dc8fde0be1d79ac810d39" + integrity sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA== + "@types/mime@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" @@ -12373,6 +12473,11 @@ linkify-it@^5.0.0: dependencies: uc.micro "^2.0.0" +linkifyjs@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.3.tgz#0edbc346428a7390a23ea2e5939f76112c9ae07f" + integrity sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg== + lit-element@^3.3.0: version "3.3.3" resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-3.3.3.tgz#10bc19702b96ef5416cf7a70177255bfb17b3209" @@ -12745,6 +12850,11 @@ markdown-escapes@^1.0.0: resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== +markdown-it-task-lists@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz#f68f4d2ac2bad5a2c373ba93081a1a6848417088" + integrity sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA== + markdown-it@13.0.1: version "13.0.1" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430" @@ -12756,6 +12866,17 @@ markdown-it@13.0.1: mdurl "^1.0.1" uc.micro "^1.0.5" +markdown-it@^13.0.1: + version "13.0.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.2.tgz#1bc22e23379a6952e5d56217fbed881e0c94d536" + integrity sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w== + dependencies: + argparse "^2.0.1" + entities "~3.0.1" + linkify-it "^4.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + markdown-it@^14.0.0: version "14.0.0" resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-14.0.0.tgz#b4b2ddeb0f925e88d981f84c183b59bac9e3741b" @@ -13256,11 +13377,16 @@ moment-timezone@0.5.43: dependencies: moment "^2.29.4" -moment@2.29.4, moment@^2.29.4: +moment@^2.29.4: version "2.29.4" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== +moment@^2.30.1: + version "2.30.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -15454,21 +15580,21 @@ property-information@^5.0.0, property-information@^5.3.0: dependencies: xtend "^4.0.0" -prosemirror-changeset@^2.2.0: +prosemirror-changeset@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz#dae94b63aec618fac7bb9061648e6e2a79988383" integrity sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ== dependencies: prosemirror-transform "^1.0.0" -prosemirror-collab@^1.3.0: +prosemirror-collab@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz#0e8c91e76e009b53457eb3b3051fb68dad029a33" integrity sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ== dependencies: prosemirror-state "^1.0.0" -prosemirror-commands@^1.0.0, prosemirror-commands@^1.3.1: +prosemirror-commands@^1.0.0, prosemirror-commands@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz#e94aeea52286f658cd984270de9b4c3fff580852" integrity sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ== @@ -15477,7 +15603,7 @@ prosemirror-commands@^1.0.0, prosemirror-commands@^1.3.1: prosemirror-state "^1.0.0" prosemirror-transform "^1.0.0" -prosemirror-dropcursor@^1.5.0: +prosemirror-dropcursor@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz#49b9fb2f583e0d0f4021ff87db825faa2be2832d" integrity sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw== @@ -15486,7 +15612,7 @@ prosemirror-dropcursor@^1.5.0: prosemirror-transform "^1.1.0" prosemirror-view "^1.1.0" -prosemirror-gapcursor@^1.3.1: +prosemirror-gapcursor@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz#5fa336b83789c6199a7341c9493587e249215cb4" integrity sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ== @@ -15496,7 +15622,7 @@ prosemirror-gapcursor@^1.3.1: prosemirror-state "^1.0.0" prosemirror-view "^1.0.0" -prosemirror-history@^1.0.0, prosemirror-history@^1.3.0: +prosemirror-history@^1.0.0, prosemirror-history@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.3.2.tgz#ce6ad7ab9db83e761aee716f3040d74738311b15" integrity sha512-/zm0XoU/N/+u7i5zepjmZAEnpvjDtzoPWW6VmKptcAnPadN/SStsBjMImdCEbb3seiNTpveziPTIrXQbHLtU1g== @@ -15506,15 +15632,15 @@ prosemirror-history@^1.0.0, prosemirror-history@^1.3.0: prosemirror-view "^1.31.0" rope-sequence "^1.3.0" -prosemirror-inputrules@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.3.0.tgz#d43ce469ffe09a1b4cbac3f0ad367b0e4b504875" - integrity sha512-z1GRP2vhh5CihYMQYsJSa1cOwXb3SYxALXOIfAkX8nZserARtl9LiL+CEl+T+OFIsXc3mJIHKhbsmRzC0HDAXA== +prosemirror-inputrules@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz#ef1519bb2cb0d1e0cec74bad1a97f1c1555068bb" + integrity sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg== dependencies: prosemirror-state "^1.0.0" prosemirror-transform "^1.0.0" -prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.2.0: +prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz#14a54763a29c7b2704f561088ccf3384d14eb77e" integrity sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ== @@ -15522,7 +15648,7 @@ prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.2.0: prosemirror-state "^1.0.0" w3c-keyname "^2.2.0" -prosemirror-markdown@^1.10.1: +prosemirror-markdown@^1.11.1, prosemirror-markdown@^1.12.0: version "1.12.0" resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.12.0.tgz#d2de09d37897abf7adb6293d925ff132dac5b0a6" integrity sha512-6F5HS8Z0HDYiS2VQDZzfZP6A0s/I0gbkJy8NCzzDMtcsz3qrfqyroMMeoSjAmOhDITyon11NbXSzztfKi+frSQ== @@ -15530,7 +15656,7 @@ prosemirror-markdown@^1.10.1: markdown-it "^14.0.0" prosemirror-model "^1.0.0" -prosemirror-menu@^1.2.1: +prosemirror-menu@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz#3cfdc7c06d10f9fbd1bce29082c498bd11a0a79a" integrity sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA== @@ -15540,21 +15666,21 @@ prosemirror-menu@^1.2.1: prosemirror-history "^1.0.0" prosemirror-state "^1.0.0" -prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.18.1, prosemirror-model@^1.19.0, prosemirror-model@^1.8.1: +prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.19.0, prosemirror-model@^1.19.4, prosemirror-model@^1.8.1: version "1.19.4" resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.19.4.tgz#e45e84480c97dd3922095dbe579e1c98c86c0704" integrity sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ== dependencies: orderedmap "^2.0.0" -prosemirror-schema-basic@^1.2.0: +prosemirror-schema-basic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.2.tgz#6695f5175e4628aab179bf62e5568628b9cfe6c7" integrity sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw== dependencies: prosemirror-model "^1.19.0" -prosemirror-schema-list@^1.2.2: +prosemirror-schema-list@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.3.0.tgz#05374702cf35a3ba5e7ec31079e355a488d52519" integrity sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A== @@ -15563,7 +15689,7 @@ prosemirror-schema-list@^1.2.2: prosemirror-state "^1.0.0" prosemirror-transform "^1.7.3" -prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.4.1: +prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.3.tgz#94aecf3ffd54ec37e87aa7179d13508da181a080" integrity sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q== @@ -15572,7 +15698,7 @@ prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, pr prosemirror-transform "^1.0.0" prosemirror-view "^1.27.0" -prosemirror-tables@^1.3.0: +prosemirror-tables@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.3.5.tgz#80f03394f5b9991f9693bcb3a90b6dba6b16254d" integrity sha512-JSZ2cCNlApu/ObAhdPyotrjBe2cimniniTpz60YXzbL0kZ+47nEYk2LWbfKU2lKpBkUNquta2PjteoNi4YCluQ== @@ -15583,7 +15709,7 @@ prosemirror-tables@^1.3.0: prosemirror-transform "^1.2.1" prosemirror-view "^1.13.3" -prosemirror-trailing-node@^2.0.2: +prosemirror-trailing-node@^2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.7.tgz#ba782a7929f18bcae650b1c7082a2d10443eab19" integrity sha512-8zcZORYj/8WEwsGo6yVCRXFMOfBo0Ub3hCUvmoWIZYfMP26WqENU0mpEP27w7mt8buZWuGrydBewr0tOArPb1Q== @@ -15592,14 +15718,14 @@ prosemirror-trailing-node@^2.0.2: "@remirror/core-helpers" "^3.0.0" escape-string-regexp "^4.0.0" -prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.7.0, prosemirror-transform@^1.7.3: +prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.7.3, prosemirror-transform@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.8.0.tgz#a47c64a3c373c1bd0ff46e95be3210c8dda0cd11" integrity sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A== dependencies: prosemirror-model "^1.0.0" -prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.28.2, prosemirror-view@^1.31.0: +prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0: version "1.32.6" resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.32.6.tgz#8e8a366ea1ce9b59dbb7f4c6fa7aacf4af2532d7" integrity sha512-26r5LvyDlPgUNVf7ZdNdGrMJnylwjJtUJTfDuYOANIVx9lqWD1WCBlGg283weYQGKUC64DXR25LeAmliB9CrFQ== @@ -15608,6 +15734,15 @@ prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, pros prosemirror-state "^1.0.0" prosemirror-transform "^1.1.0" +prosemirror-view@^1.32.7: + version "1.33.1" + resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.33.1.tgz#58dfd154f4fb1c9f7353bf1097c54d6afc6f57ea" + integrity sha512-62qkYgSJIkwIMMCpuGuPzc52DiK1Iod6TWoIMxP4ja6BTD4yO8kCUL64PZ/WhH/dJ9fW0CDO39FhH1EMyhUFEg== + dependencies: + prosemirror-model "^1.16.0" + prosemirror-state "^1.0.0" + prosemirror-transform "^1.1.0" + proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" @@ -17847,6 +17982,16 @@ tippy.js@^6.3.7: dependencies: "@popperjs/core" "^2.9.0" +tiptap-markdown@^0.8.9: + version "0.8.9" + resolved "https://registry.yarnpkg.com/tiptap-markdown/-/tiptap-markdown-0.8.9.tgz#e13f3ae9a1b1649f8c28bb3cae4516a53da7492c" + integrity sha512-TykSDcsb94VFCzPbSSTfB6Kh2HJi7x4B9J3Jm9uSOAMPy8App1YfrLW/rEJLajTxwMVhWBdOo4nidComSlLQsQ== + dependencies: + "@types/markdown-it" "^12.2.3" + markdown-it "^13.0.1" + markdown-it-task-lists "^2.1.1" + prosemirror-markdown "^1.11.1" + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"