mirror of
https://github.com/docusealco/docuseal.git
synced 2026-08-07 07:14:43 +00:00
add markdown editor
This commit is contained in:
committed by
Pete Matsyburka
parent
451f83421a
commit
39cc82ce0c
@@ -40,6 +40,7 @@ import DashboardDropzone from './elements/dashboard_dropzone'
|
||||
import RequiredCheckboxGroup from './elements/required_checkbox_group'
|
||||
import PageContainer from './elements/page_container'
|
||||
import EmailEditor from './elements/email_editor'
|
||||
import MarkdownEditor from './elements/markdown_editor'
|
||||
import MountOnClick from './elements/mount_on_click'
|
||||
import RemoveOnEvent from './elements/remove_on_event'
|
||||
import ScrollTo from './elements/scroll_to'
|
||||
@@ -131,6 +132,7 @@ safeRegisterElement('check-on-click', CheckOnClick)
|
||||
safeRegisterElement('required-checkbox-group', RequiredCheckboxGroup)
|
||||
safeRegisterElement('page-container', PageContainer)
|
||||
safeRegisterElement('email-editor', EmailEditor)
|
||||
safeRegisterElement('markdown-editor', MarkdownEditor)
|
||||
safeRegisterElement('mount-on-click', MountOnClick)
|
||||
safeRegisterElement('remove-on-event', RemoveOnEvent)
|
||||
safeRegisterElement('scroll-to', ScrollTo)
|
||||
|
||||
@@ -0,0 +1,411 @@
|
||||
import { target, targetable } from '@github/catalyst/lib/targetable'
|
||||
|
||||
function loadTiptap () {
|
||||
return Promise.all([
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/core'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/extension-bold'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/extension-italic'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/extension-paragraph'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/extension-text'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/extension-hard-break'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/extension-document'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/extension-link'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/extension-underline'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/extensions'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/markdown'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/pm/state'),
|
||||
import(/* webpackChunkName: "markdown-editor" */ '@tiptap/pm/view')
|
||||
]).then(([core, bold, italic, paragraph, text, hardBreak, document, link, underline, extensions, markdown, pmState, pmView]) => ({
|
||||
Editor: core.Editor,
|
||||
Extension: core.Extension,
|
||||
Bold: bold.default || bold,
|
||||
Italic: italic.default || italic,
|
||||
Paragraph: paragraph.default || paragraph,
|
||||
Text: text.default || text,
|
||||
HardBreak: hardBreak.default || hardBreak,
|
||||
Document: document.default || document,
|
||||
Link: link.default || link,
|
||||
Underline: underline.default || underline,
|
||||
UndoRedo: extensions.UndoRedo,
|
||||
Markdown: markdown.Markdown,
|
||||
Plugin: pmState.Plugin,
|
||||
Decoration: pmView.Decoration,
|
||||
DecorationSet: pmView.DecorationSet
|
||||
}))
|
||||
}
|
||||
|
||||
class LinkTooltip {
|
||||
constructor (tooltip, input, saveButton, removeButton, normalizeUrlFn) {
|
||||
this.tooltip = tooltip
|
||||
this.input = input
|
||||
this.saveButton = saveButton
|
||||
this.removeButton = removeButton
|
||||
this.normalizeUrl = normalizeUrlFn
|
||||
this.targetElement = null
|
||||
this.clickOutsideTimeout = null
|
||||
this.closeOnClickOutside = null
|
||||
this.scrollHandler = null
|
||||
this.saveHandler = null
|
||||
this.removeHandler = null
|
||||
this.keyHandler = null
|
||||
}
|
||||
|
||||
updatePosition () {
|
||||
const rect = this.targetElement.getBoundingClientRect()
|
||||
this.tooltip.style.left = `${rect.left}px`
|
||||
this.tooltip.style.top = `${rect.bottom + 5}px`
|
||||
}
|
||||
|
||||
setupClickOutside () {
|
||||
this.closeOnClickOutside = (e) => {
|
||||
if (!this.tooltip.contains(e.target)) {
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
|
||||
this.clickOutsideTimeout = setTimeout(() => {
|
||||
if (this.closeOnClickOutside) {
|
||||
document.addEventListener('click', this.closeOnClickOutside)
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
|
||||
setupScrollTracking () {
|
||||
this.scrollHandler = () => this.updatePosition()
|
||||
window.addEventListener('scroll', this.scrollHandler, true)
|
||||
}
|
||||
|
||||
show ({ url, targetElement, onSave, onRemove }) {
|
||||
this.hide()
|
||||
|
||||
this.input.value = url || ''
|
||||
this.removeButton.classList.toggle('hidden', !url)
|
||||
this.targetElement = targetElement
|
||||
|
||||
this.updatePosition()
|
||||
|
||||
this.tooltip.classList.remove('hidden')
|
||||
this.input.focus()
|
||||
this.input.select()
|
||||
|
||||
const save = () => {
|
||||
const inputUrl = this.input.value.trim()
|
||||
|
||||
this.hide()
|
||||
|
||||
if (inputUrl) {
|
||||
onSave(this.normalizeUrl(inputUrl))
|
||||
}
|
||||
}
|
||||
|
||||
this.saveHandler = () => save()
|
||||
this.removeHandler = () => {
|
||||
if (onRemove) onRemove()
|
||||
this.hide()
|
||||
}
|
||||
this.keyHandler = (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault()
|
||||
save()
|
||||
} else if (e.key === 'Escape') {
|
||||
e.preventDefault()
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
|
||||
this.saveButton.addEventListener('click', this.saveHandler, { once: true })
|
||||
this.removeButton.addEventListener('click', this.removeHandler, { once: true })
|
||||
this.input.addEventListener('keydown', this.keyHandler)
|
||||
|
||||
this.setupScrollTracking()
|
||||
this.setupClickOutside()
|
||||
}
|
||||
|
||||
hide () {
|
||||
if (this.clickOutsideTimeout) {
|
||||
clearTimeout(this.clickOutsideTimeout)
|
||||
this.clickOutsideTimeout = null
|
||||
}
|
||||
|
||||
if (this.scrollHandler) {
|
||||
window.removeEventListener('scroll', this.scrollHandler, true)
|
||||
this.scrollHandler = null
|
||||
}
|
||||
|
||||
if (this.closeOnClickOutside) {
|
||||
document.removeEventListener('click', this.closeOnClickOutside)
|
||||
this.closeOnClickOutside = null
|
||||
}
|
||||
|
||||
if (this.saveHandler) {
|
||||
this.saveButton.removeEventListener('click', this.saveHandler)
|
||||
this.saveHandler = null
|
||||
}
|
||||
|
||||
if (this.removeHandler) {
|
||||
this.removeButton.removeEventListener('click', this.removeHandler)
|
||||
this.removeHandler = null
|
||||
}
|
||||
|
||||
if (this.keyHandler) {
|
||||
this.input.removeEventListener('keydown', this.keyHandler)
|
||||
this.keyHandler = null
|
||||
}
|
||||
|
||||
this.tooltip?.classList.add('hidden')
|
||||
this.targetElement = null
|
||||
}
|
||||
}
|
||||
|
||||
export default targetable(class extends HTMLElement {
|
||||
static [target.static] = [
|
||||
'textarea',
|
||||
'editorElement',
|
||||
'variableButton',
|
||||
'variableDropdown',
|
||||
'boldButton',
|
||||
'italicButton',
|
||||
'underlineButton',
|
||||
'linkButton',
|
||||
'undoButton',
|
||||
'redoButton',
|
||||
'linkTooltipElement',
|
||||
'linkInput',
|
||||
'linkSaveButton',
|
||||
'linkRemoveButton'
|
||||
]
|
||||
|
||||
async connectedCallback () {
|
||||
if (!this.textarea || !this.editorElement) return
|
||||
|
||||
this.textarea.style.display = 'none'
|
||||
this.adjustShortcutsForPlatform()
|
||||
|
||||
this.linkTooltip = new LinkTooltip(
|
||||
this.linkTooltipElement,
|
||||
this.linkInput,
|
||||
this.linkSaveButton,
|
||||
this.linkRemoveButton,
|
||||
(url) => this.normalizeUrl(url)
|
||||
)
|
||||
|
||||
const { Editor, Extension, Bold, Italic, Paragraph, Text, HardBreak, UndoRedo, Document, Link, Underline, Markdown, Plugin, Decoration, DecorationSet } = await loadTiptap()
|
||||
|
||||
const buildDecorations = (doc) => {
|
||||
const decorations = []
|
||||
const regex = /\{[a-zA-Z0-9_.-]+\}/g
|
||||
|
||||
doc.descendants((node, pos) => {
|
||||
if (!node.isText) return
|
||||
|
||||
let match
|
||||
|
||||
while ((match = regex.exec(node.text)) !== null) {
|
||||
decorations.push(
|
||||
Decoration.inline(pos + match.index, pos + match.index + match[0].length, {
|
||||
class: 'bg-amber-100 py-0.5 px-1 rounded'
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
return DecorationSet.create(doc, decorations)
|
||||
}
|
||||
|
||||
const VariableHighlight = Extension.create({
|
||||
name: 'variableHighlight',
|
||||
addProseMirrorPlugins () {
|
||||
return [new Plugin({
|
||||
state: {
|
||||
init (_, { doc }) {
|
||||
return buildDecorations(doc)
|
||||
},
|
||||
apply (tr, oldSet) {
|
||||
return tr.docChanged ? buildDecorations(tr.doc) : oldSet
|
||||
}
|
||||
},
|
||||
props: {
|
||||
decorations (state) {
|
||||
return this.getState(state)
|
||||
}
|
||||
}
|
||||
})]
|
||||
}
|
||||
})
|
||||
|
||||
this.editor = new Editor({
|
||||
element: this.editorElement,
|
||||
extensions: [
|
||||
Markdown,
|
||||
Document,
|
||||
Paragraph,
|
||||
Text,
|
||||
Bold,
|
||||
Italic,
|
||||
HardBreak,
|
||||
UndoRedo,
|
||||
Link.extend({
|
||||
inclusive: false
|
||||
}).configure({
|
||||
openOnClick: false,
|
||||
HTMLAttributes: {
|
||||
class: 'link',
|
||||
style: 'color: #2563eb; text-decoration: underline; cursor: pointer;'
|
||||
}
|
||||
}),
|
||||
Underline,
|
||||
VariableHighlight
|
||||
],
|
||||
content: this.textarea.value || '',
|
||||
contentType: 'markdown',
|
||||
editorProps: {
|
||||
attributes: {
|
||||
class: 'prose prose-sm max-w-none p-3 outline-none focus:outline-none min-h-[120px]'
|
||||
},
|
||||
handleClick: (view, pos, event) => {
|
||||
const clickedPos = view.posAtCoords({ left: event.clientX, top: event.clientY })
|
||||
|
||||
if (!clickedPos) return false
|
||||
|
||||
const linkMark = view.state.doc.resolve(clickedPos.pos).marks().find(m => m.type.name === 'link')
|
||||
|
||||
if (linkMark) {
|
||||
event.preventDefault()
|
||||
|
||||
this.editor.chain().setTextSelection(clickedPos.pos).extendMarkRange('link').run()
|
||||
this.toggleLink()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
},
|
||||
onUpdate: ({ editor }) => {
|
||||
this.textarea.value = editor.getMarkdown()
|
||||
this.textarea.dispatchEvent(new Event('input', { bubbles: true }))
|
||||
},
|
||||
onSelectionUpdate: () => {
|
||||
this.updateToolbarState()
|
||||
}
|
||||
})
|
||||
|
||||
this.setupToolbar()
|
||||
|
||||
if (this.variableButton) {
|
||||
this.variableButton.addEventListener('click', () => {
|
||||
this.variableDropdown.classList.toggle('hidden')
|
||||
})
|
||||
|
||||
this.variableDropdown.addEventListener('click', (e) => {
|
||||
const variable = e.target.closest('[data-variable]')?.dataset.variable
|
||||
|
||||
if (variable) {
|
||||
this.insertVariable(variable)
|
||||
this.variableDropdown.classList.add('hidden')
|
||||
}
|
||||
})
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!this.variableButton.contains(e.target) && !this.variableDropdown.contains(e.target)) {
|
||||
this.variableDropdown.classList.add('hidden')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
adjustShortcutsForPlatform () {
|
||||
if ((navigator.userAgentData?.platform || navigator.platform)?.toLowerCase()?.includes('mac')) {
|
||||
this.querySelectorAll('.tooltip[data-tip]').forEach(tooltip => {
|
||||
const tip = tooltip.getAttribute('data-tip')
|
||||
|
||||
if (tip && tip.includes('Ctrl')) {
|
||||
tooltip.setAttribute('data-tip', tip.replace(/Ctrl/g, '⌘'))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setupToolbar () {
|
||||
this.boldButton?.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
this.editor.chain().focus().toggleBold().run()
|
||||
this.updateToolbarState()
|
||||
})
|
||||
|
||||
this.italicButton?.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
this.editor.chain().focus().toggleItalic().run()
|
||||
this.updateToolbarState()
|
||||
})
|
||||
|
||||
this.underlineButton?.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
this.editor.chain().focus().toggleUnderline().run()
|
||||
this.updateToolbarState()
|
||||
})
|
||||
|
||||
this.linkButton?.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
this.toggleLink()
|
||||
})
|
||||
|
||||
this.undoButton?.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
this.editor.chain().focus().undo().run()
|
||||
})
|
||||
|
||||
this.redoButton?.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
this.editor.chain().focus().redo().run()
|
||||
})
|
||||
}
|
||||
|
||||
updateToolbarState () {
|
||||
this.boldButton?.classList.toggle('bg-base-200', this.editor.isActive('bold'))
|
||||
this.italicButton?.classList.toggle('bg-base-200', this.editor.isActive('italic'))
|
||||
this.underlineButton?.classList.toggle('bg-base-200', this.editor.isActive('underline'))
|
||||
this.linkButton?.classList.toggle('bg-base-200', this.editor.isActive('link'))
|
||||
}
|
||||
|
||||
normalizeUrl (url) {
|
||||
if (!url) return url
|
||||
if (/^https?:\/\//i.test(url)) return url
|
||||
if (/^mailto:/i.test(url)) return url
|
||||
|
||||
return `https://${url}`
|
||||
}
|
||||
|
||||
toggleLink () {
|
||||
const { from } = this.editor.state.selection
|
||||
|
||||
const rect = this.editor.view.coordsAtPos(from)
|
||||
const fakeElement = { getBoundingClientRect: () => rect }
|
||||
|
||||
const previousUrl = this.editor.getAttributes('link').href
|
||||
|
||||
this.linkTooltip.show({
|
||||
url: previousUrl,
|
||||
targetElement: fakeElement,
|
||||
onSave: (url) => {
|
||||
this.editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run()
|
||||
},
|
||||
onRemove: previousUrl
|
||||
? () => { this.editor.chain().focus().extendMarkRange('link').unsetLink().run() }
|
||||
: null
|
||||
})
|
||||
}
|
||||
|
||||
insertVariable (variable) {
|
||||
this.editor.chain().focus().insertContent(`{${variable}}`).run()
|
||||
}
|
||||
|
||||
disconnectedCallback () {
|
||||
this.linkTooltip.hide()
|
||||
|
||||
if (this.editor) {
|
||||
this.editor.destroy()
|
||||
this.editor = null
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg class="<%= local_assigns[:class] %>" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M9 14l-4 -4l4 -4" />
|
||||
<path d="M5 10h11a4 4 0 1 1 0 8h-1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 354 B |
@@ -0,0 +1,5 @@
|
||||
<svg class="<%= local_assigns[:class] %>" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M15 14l4 -4l-4 -4" />
|
||||
<path d="M19 10h-11a4 4 0 1 0 0 8h1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 356 B |
@@ -0,0 +1,5 @@
|
||||
<svg class="<%= local_assigns[:class] %>" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M7 5h6a3.5 3.5 0 0 1 0 7h-6l0 -7" />
|
||||
<path d="M13 12h1a3.5 3.5 0 0 1 0 7h-7v-7" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 377 B |
@@ -0,0 +1,6 @@
|
||||
<svg class="<%= local_assigns[:class] %>" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M11 5l6 0" />
|
||||
<path d="M7 19l6 0" />
|
||||
<path d="M14 5l-4 14" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 358 B |
@@ -0,0 +1,5 @@
|
||||
<svg class="<%= local_assigns[:class] %>" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M7 5v5a5 5 0 0 0 10 0v-5" />
|
||||
<path d="M5 19h14" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 345 B |
@@ -1,11 +1,5 @@
|
||||
<div class="form-control">
|
||||
<div class="flex items-center">
|
||||
<%= ff.label :body, t('body'), class: 'label' %>
|
||||
<span class="tooltip" data-tip="<%= t('use_following_placeholders_text_') %> <%= AccountConfig::DEFAULT_VALUES[local_assigns[:config].key].call['body'].scan(/{.*?}/).join(', ') %>">
|
||||
<%= svg_icon('info_circle', class: 'w-4 h-4') %>
|
||||
</span>
|
||||
</div>
|
||||
<autoresize-textarea>
|
||||
<%= ff.text_area :body, required: true, class: 'base-input w-full !rounded-2xl py-2', dir: 'auto' %>
|
||||
</autoresize-textarea>
|
||||
<%= ff.label :body, t('body'), class: 'label' %>
|
||||
<% variables = AccountConfig::DEFAULT_VALUES[local_assigns[:config].key].call['body'].scan(/\{([^}]+)\}/).flatten.uniq %>
|
||||
<%= render 'personalization_settings/markdown_editor', name: ff.field_name(:body), value: local_assigns[:config].value['body'], variables: variables %>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<markdown-editor>
|
||||
<div class="border border-base-content/20 rounded-2xl bg-white">
|
||||
<div class="flex items-center px-2 py-2 border-b" style="height: 42px;">
|
||||
<div class="flex items-center gap-1">
|
||||
<div class="tooltip tooltip-top" data-tip="<%= t('bold') %> (Ctrl+B)">
|
||||
<button type="button" data-target="markdown-editor.boldButton" aria-label="<%= t('bold') %>" class="flex items-center px-1 w-6 h-6 rounded hover:bg-base-300">
|
||||
<%= svg_icon('bold', class: 'w-4 h-4') %>
|
||||
</button>
|
||||
</div>
|
||||
<div class="tooltip tooltip-top" data-tip="<%= t('italic') %> (Ctrl+I)">
|
||||
<button type="button" data-target="markdown-editor.italicButton" aria-label="<%= t('italic') %>" class="flex items-center px-1 w-6 h-6 rounded hover:bg-base-300">
|
||||
<%= svg_icon('italic', class: 'w-4 h-4') %>
|
||||
</button>
|
||||
</div>
|
||||
<div class="tooltip tooltip-top" data-tip="<%= t('underline') %> (Ctrl+U)">
|
||||
<button type="button" data-target="markdown-editor.underlineButton" aria-label="<%= t('underline') %>" class="flex items-center px-1 w-6 h-6 rounded hover:bg-base-300">
|
||||
<%= svg_icon('underline', class: 'w-4 h-4') %>
|
||||
</button>
|
||||
</div>
|
||||
<div class="tooltip tooltip-top" data-tip="<%= t('link') %> (Ctrl+K)">
|
||||
<button type="button" data-target="markdown-editor.linkButton" aria-label="<%= t('link') %>" class="flex items-center px-1 w-6 h-6 rounded hover:bg-base-300">
|
||||
<%= svg_icon('link', class: 'w-4 h-4') %>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-2 h-5 border-l border-base-content/20"></div>
|
||||
<div class="flex items-center gap-1">
|
||||
<div class="tooltip tooltip-top" data-tip="<%= t('undo') %> (Ctrl+Z)">
|
||||
<button type="button" data-target="markdown-editor.undoButton" aria-label="<%= t('undo') %>" class="flex items-center px-1 w-6 h-6 rounded hover:bg-base-300">
|
||||
<%= svg_icon('arrow_back_up', class: 'w-4 h-4') %>
|
||||
</button>
|
||||
</div>
|
||||
<div class="tooltip tooltip-top" data-tip="<%= t('redo') %> (Ctrl+Shift+Z)">
|
||||
<button type="button" data-target="markdown-editor.redoButton" aria-label="<%= t('redo') %>" class="flex items-center px-1 w-6 h-6 rounded hover:bg-base-300">
|
||||
<%= svg_icon('arrow_forward_up', class: 'w-4 h-4') %>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<% if local_assigns[:variables]&.any? %>
|
||||
<% variable_labels = { 'account.name' => t('variables.account_name'), 'submitter.link' => t('variables.submitter_link'), 'code' => t('variables.code'), 'template.name' => t('variables.template_name'), 'submission.submitters' => t('variables.submission_submitters'), 'submission.link' => t('variables.submission_link'), 'documents.link' => t('variables.documents_link') } %>
|
||||
<div class="ml-auto relative">
|
||||
<button type="button" data-target="markdown-editor.variableButton" class="flex items-center gap-1 text-sm px-2 py-1 rounded hover:bg-base-200 cursor-pointer">
|
||||
<%= t('add_variable') %>
|
||||
<%= svg_icon('chevron_down', class: 'w-3.5 h-3.5') %>
|
||||
</button>
|
||||
<div data-target="markdown-editor.variableDropdown" class="hidden absolute right-0 top-full mt-1 p-1 bg-white border border-neutral-200 rounded-lg shadow-lg z-50">
|
||||
<% local_assigns[:variables]&.each do |variable| %>
|
||||
<button type="button" data-variable="<%= variable %>" class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 text-left text-sm cursor-pointer whitespace-nowrap">
|
||||
<%= variable_labels.fetch(variable, "{#{variable}}") %>
|
||||
</button>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div data-target="markdown-editor.editorElement"></div>
|
||||
</div>
|
||||
<div data-target="markdown-editor.linkTooltipElement" class="hidden fixed flex bg-white border border-base-300 rounded-xl shadow-lg p-1 gap-1 items-center z-50">
|
||||
<input data-target="markdown-editor.linkInput" type="text" placeholder="<%= t('enter_a_url_or_variable_name') %>" class="rounded-lg border border-base-300 px-2 py-1 w-80 text-sm outline-none" autocomplete="off">
|
||||
<button type="button" data-target="markdown-editor.linkSaveButton" class="flex items-center px-1 w-6 h-6 rounded hover:bg-success/10 cursor-pointer">
|
||||
<%= svg_icon('check', class: 'w-4 h-4 text-success') %>
|
||||
</button>
|
||||
<button type="button" data-target="markdown-editor.linkRemoveButton" class="flex items-center px-1 w-6 h-6 rounded hover:bg-error/10 cursor-pointer">
|
||||
<%= svg_icon('x', class: 'w-4 h-4 text-error') %>
|
||||
</button>
|
||||
</div>
|
||||
<%= hidden_field_tag name, value, required: true, data: { target: 'markdown-editor.textarea' } %>
|
||||
</markdown-editor>
|
||||
@@ -55,15 +55,9 @@
|
||||
<%= f.text_field :subject, value: local_assigns[:submitter_email_message]&.subject.presence || submitter_preferences_index.dig(local_assigns[:submitter]&.uuid, 'request_email_subject').presence || template&.preferences&.dig('request_email_subject').presence || config.value['subject'], required: true, class: '!text-sm base-input w-full', dir: 'auto' %>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<div class="flex items-center">
|
||||
<%= f.label :message, t('body'), class: 'label' %>
|
||||
<span class="tooltip tooltip-right" data-tip="<%= t('use_following_placeholders_text_') %> <%= AccountConfig::DEFAULT_VALUES[AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY].call['body'].scan(/{.*?}/).join(', ') %>">
|
||||
<%= svg_icon('info_circle', class: 'w-4 h-4') %>
|
||||
</span>
|
||||
</div>
|
||||
<autoresize-textarea>
|
||||
<%= f.text_area :body, value: local_assigns[:submitter_email_message]&.body.presence || submitter_preferences_index.dig(local_assigns[:submitter]&.uuid, 'request_email_body').presence || template&.preferences&.dig('request_email_body').presence || config.value['body'], required: true, class: 'base-textarea w-full', rows: 10, dir: 'auto' %>
|
||||
</autoresize-textarea>
|
||||
<%= f.label :message, t('body'), class: 'label' %>
|
||||
<% body_variables = AccountConfig::DEFAULT_VALUES[AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY].call['body'].scan(/\{([^}]+)\}/).flatten.uniq %>
|
||||
<%= render 'personalization_settings/markdown_editor', name: f.field_name(:body), value: local_assigns[:submitter_email_message]&.body.presence || submitter_preferences_index.dig(local_assigns[:submitter]&.uuid, 'request_email_body').presence || template&.preferences&.dig('request_email_body').presence || config.value['body'], variables: body_variables %>
|
||||
<% unless local_assigns.fetch(:disable_save_as_default_template_option, false) %>
|
||||
<label for="<%= uuid = SecureRandom.uuid %>" class="flex items-center cursor-pointer">
|
||||
<%= check_box_tag :save_message, id: uuid, class: 'base-checkbox', checked: false %>
|
||||
@@ -97,15 +91,8 @@
|
||||
<%= ff.text_field :subject, value: local_assigns[:submitter_email_message]&.subject.presence || submitter_preferences_index.dig(submitter['uuid'], 'request_email_subject').presence || template&.preferences&.dig('request_email_subject').presence || config.value['subject'], required: true, class: '!text-sm base-input w-full', dir: 'auto' %>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<div class="flex items-center">
|
||||
<%= ff.label :message, t('body'), class: 'label' %>
|
||||
<span class="tooltip tooltip-right" data-tip="<%= t('use_following_placeholders_text_') %> <%= AccountConfig::DEFAULT_VALUES[AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY].call['body'].scan(/{.*?}/).join(', ') %>">
|
||||
<%= svg_icon('info_circle', class: 'w-4 h-4') %>
|
||||
</span>
|
||||
</div>
|
||||
<autoresize-textarea>
|
||||
<%= ff.text_area :body, value: local_assigns[:submitter_email_message]&.body.presence || submitter_preferences_index.dig(submitter['uuid'], 'request_email_body').presence || template&.preferences&.dig('request_email_body').presence || config.value['body'], required: true, class: 'base-textarea w-full', rows: 10, dir: 'auto' %>
|
||||
</autoresize-textarea>
|
||||
<%= ff.label :message, t('body'), class: 'label' %>
|
||||
<%= render 'personalization_settings/markdown_editor', name: ff.field_name(:body), value: local_assigns[:submitter_email_message]&.body.presence || submitter_preferences_index.dig(submitter['uuid'], 'request_email_body').presence || template&.preferences&.dig('request_email_body').presence || config.value['body'], variables: body_variables %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -887,6 +887,13 @@ en: &en
|
||||
if_you_didnt_request_this_you_can_ignore_this_email: "If you didn't request this, please ignore this email."
|
||||
your_password_wont_change_until_you_open_the_link_above_and_set_a_new_one: "Your password won't change until you open the link above and set a new one."
|
||||
too_many_requests_try_again_later: Too many requests, try again later.
|
||||
bold: Bold
|
||||
italic: Italic
|
||||
underline: Underline
|
||||
undo: Undo
|
||||
redo: Redo
|
||||
add_variable: Add variable
|
||||
enter_a_url_or_variable_name: Enter a URL or variable name
|
||||
devise:
|
||||
confirmations:
|
||||
confirmed: Your email address has been successfully confirmed.
|
||||
@@ -1003,6 +1010,13 @@ en: &en
|
||||
events:
|
||||
range_with_total: "%{from}-%{to} of %{count} events"
|
||||
range_without_total: "%{from}-%{to} events"
|
||||
variables:
|
||||
account_name: Account name
|
||||
submitter_link: Submitter link
|
||||
template_name: Template name
|
||||
submission_submitters: Submission submitters
|
||||
submission_link: Submission link
|
||||
documents_link: Documents link
|
||||
time:
|
||||
formats:
|
||||
detailed: "%B %d, %Y %H:%M:%S"
|
||||
@@ -1875,6 +1889,13 @@ es: &es
|
||||
if_you_didnt_request_this_you_can_ignore_this_email: "Si no solicitaste esto, puedes ignorar este correo electrónico."
|
||||
your_password_wont_change_until_you_open_the_link_above_and_set_a_new_one: "Tu contraseña no cambiará hasta que abras el enlace anterior y establezcas una nueva."
|
||||
too_many_requests_try_again_later: Demasiadas solicitudes. Intenta de nuevo más tarde.
|
||||
bold: Negrita
|
||||
italic: Cursiva
|
||||
underline: Subrayado
|
||||
undo: Deshacer
|
||||
redo: Rehacer
|
||||
add_variable: Agregar variable
|
||||
enter_a_url_or_variable_name: Ingrese una URL o nombre de variable
|
||||
devise:
|
||||
confirmations:
|
||||
confirmed: Tu dirección de correo electrónico ha sido confirmada correctamente.
|
||||
@@ -1991,6 +2012,13 @@ es: &es
|
||||
events:
|
||||
range_with_total: "%{from}-%{to} de %{count} eventos"
|
||||
range_without_total: "%{from}-%{to} eventos"
|
||||
variables:
|
||||
account_name: Nombre de la cuenta
|
||||
submitter_link: Enlace del firmante
|
||||
template_name: Nombre de la plantilla
|
||||
submission_submitters: Firmantes del envío
|
||||
submission_link: Enlace del envío
|
||||
documents_link: Enlace de los documentos
|
||||
time:
|
||||
formats:
|
||||
detailed: "%-d de %B de %Y %H:%M:%S"
|
||||
@@ -2864,6 +2892,13 @@ it: &it
|
||||
if_you_didnt_request_this_you_can_ignore_this_email: "Se non hai richiesto questo, puoi ignorare questa email."
|
||||
your_password_wont_change_until_you_open_the_link_above_and_set_a_new_one: "La tua password non cambierà finché non apri il link sopra e ne imposti una nuova."
|
||||
too_many_requests_try_again_later: Troppe richieste. Riprova più tardi.
|
||||
bold: Grassetto
|
||||
italic: Corsivo
|
||||
underline: Sottolineato
|
||||
undo: Annulla
|
||||
redo: Ripeti
|
||||
add_variable: Aggiungi variabile
|
||||
enter_a_url_or_variable_name: Inserisci un URL o nome variabile
|
||||
devise:
|
||||
confirmations:
|
||||
confirmed: Il tuo indirizzo email è stato confermato con successo.
|
||||
@@ -2980,6 +3015,13 @@ it: &it
|
||||
events:
|
||||
range_with_total: "%{from}-%{to} di %{count} eventi"
|
||||
range_without_total: "%{from}-%{to} eventi"
|
||||
variables:
|
||||
account_name: Nome dell'account
|
||||
submitter_link: Link del firmatario
|
||||
template_name: Nome del modello
|
||||
submission_submitters: Firmatari dell'invio
|
||||
submission_link: Link dell'invio
|
||||
documents_link: Link dei documenti
|
||||
time:
|
||||
formats:
|
||||
detailed: "%d %B %Y %H:%M:%S"
|
||||
@@ -3849,6 +3891,13 @@ fr: &fr
|
||||
if_you_didnt_request_this_you_can_ignore_this_email: "Si vous n'avez pas fait cette demande, veuillez ignorer cet e-mail."
|
||||
your_password_wont_change_until_you_open_the_link_above_and_set_a_new_one: "Votre mot de passe ne changera pas tant que vous n’aurez pas ouvert le lien ci-dessus et défini un nouveau mot de passe."
|
||||
too_many_requests_try_again_later: Trop de demandes. Réessayez plus tard.
|
||||
bold: Gras
|
||||
italic: Italique
|
||||
underline: Souligné
|
||||
undo: Annuler
|
||||
redo: Rétablir
|
||||
add_variable: Ajouter une variable
|
||||
enter_a_url_or_variable_name: Entrez une URL ou un nom de variable
|
||||
devise:
|
||||
confirmations:
|
||||
confirmed: Votre adresse e-mail a été confirmée avec succès.
|
||||
@@ -3965,6 +4014,13 @@ fr: &fr
|
||||
events:
|
||||
range_with_total: "%{from}-%{to} sur %{count} événements"
|
||||
range_without_total: "%{from}-%{to} événements"
|
||||
variables:
|
||||
account_name: Nom du compte
|
||||
submitter_link: Lien du signataire
|
||||
template_name: Nom du modèle
|
||||
submission_submitters: Signataires de la soumission
|
||||
submission_link: Lien de la soumission
|
||||
documents_link: Lien des documents
|
||||
time:
|
||||
formats:
|
||||
detailed: "%A %d %B %Y %Hh%Mm%Ss"
|
||||
@@ -4837,6 +4893,13 @@ pt: &pt
|
||||
if_you_didnt_request_this_you_can_ignore_this_email: "Se você não solicitou isso, pode ignorar este e-mail."
|
||||
your_password_wont_change_until_you_open_the_link_above_and_set_a_new_one: "Sua senha não será alterada até que você abra o link acima e defina uma nova."
|
||||
too_many_requests_try_again_later: Muitas solicitações. Tente novamente mais tarde.
|
||||
bold: Negrito
|
||||
italic: Itálico
|
||||
underline: Sublinhado
|
||||
undo: Desfazer
|
||||
redo: Refazer
|
||||
add_variable: Adicionar variável
|
||||
enter_a_url_or_variable_name: Digite uma URL ou nome de variável
|
||||
devise:
|
||||
confirmations:
|
||||
confirmed: Seu endereço de e-mail foi confirmado com sucesso.
|
||||
@@ -4953,6 +5016,13 @@ pt: &pt
|
||||
events:
|
||||
range_with_total: "%{from}-%{to} de %{count} eventos"
|
||||
range_without_total: "%{from}-%{to} eventos"
|
||||
variables:
|
||||
account_name: Nome da conta
|
||||
submitter_link: Link do signatário
|
||||
template_name: Nome do modelo
|
||||
submission_submitters: Signatários da submissão
|
||||
submission_link: Link da submissão
|
||||
documents_link: Link dos documentos
|
||||
time:
|
||||
formats:
|
||||
detailed: "%A, %d de %B de %Y, %H:%M:%Sh"
|
||||
@@ -5825,6 +5895,13 @@ de: &de
|
||||
if_you_didnt_request_this_you_can_ignore_this_email: "Wenn Sie dies nicht angefordert haben, können Sie diese E-Mail ignorieren."
|
||||
your_password_wont_change_until_you_open_the_link_above_and_set_a_new_one: "Ihr Passwort wird erst geändert, wenn Sie den obigen Link öffnen und ein neues festlegen."
|
||||
too_many_requests_try_again_later: Zu viele Anfragen. Versuchen Sie es später erneut.
|
||||
bold: Fett
|
||||
italic: Kursiv
|
||||
underline: Unterstrichen
|
||||
undo: Rückgängig
|
||||
redo: Wiederholen
|
||||
add_variable: Variable hinzufügen
|
||||
enter_a_url_or_variable_name: Geben Sie eine URL oder einen Variablennamen ein
|
||||
devise:
|
||||
confirmations:
|
||||
confirmed: Ihre E-Mail-Adresse wurde erfolgreich bestätigt.
|
||||
@@ -5941,6 +6018,13 @@ de: &de
|
||||
events:
|
||||
range_with_total: "%{from}-%{to} von %{count} Ereignissen"
|
||||
range_without_total: "%{from}-%{to} Ereignisse"
|
||||
variables:
|
||||
account_name: Kontoname
|
||||
submitter_link: Link des Unterzeichners
|
||||
template_name: Vorlagenname
|
||||
submission_submitters: Unterzeichner der Einreichung
|
||||
submission_link: Link der Einreichung
|
||||
documents_link: Link der Dokumente
|
||||
time:
|
||||
formats:
|
||||
detailed: "%A, %d. %B %Y, %H:%M:%S Uhr"
|
||||
@@ -7198,6 +7282,13 @@ nl: &nl
|
||||
if_you_didnt_request_this_you_can_ignore_this_email: "Als je dit niet hebt aangevraagd, kun je deze e-mail negeren."
|
||||
your_password_wont_change_until_you_open_the_link_above_and_set_a_new_one: "Je wachtwoord wordt niet gewijzigd totdat je de bovenstaande link opent en een nieuw wachtwoord instelt."
|
||||
too_many_requests_try_again_later: Te veel verzoeken. Probeer het later opnieuw.
|
||||
bold: Vet
|
||||
italic: Cursief
|
||||
underline: Onderstreept
|
||||
undo: Ongedaan maken
|
||||
redo: Opnieuw
|
||||
add_variable: Variabele toevoegen
|
||||
enter_a_url_or_variable_name: Voer een URL of variabelenaam in
|
||||
devise:
|
||||
confirmations:
|
||||
confirmed: Je e-mailadres is succesvol bevestigd.
|
||||
@@ -7314,6 +7405,13 @@ nl: &nl
|
||||
events:
|
||||
range_with_total: "%{from}-%{to} van %{count} gebeurtenissen"
|
||||
range_without_total: "%{from}-%{to} gebeurtenissen"
|
||||
variables:
|
||||
account_name: Accountnaam
|
||||
submitter_link: Link van de ondertekenaar
|
||||
template_name: Sjabloonnaam
|
||||
submission_submitters: Ondertekenaars van de inzending
|
||||
submission_link: Link van de inzending
|
||||
documents_link: Link van de documenten
|
||||
time:
|
||||
formats:
|
||||
detailed: "%d %B %Y %H:%M:%S"
|
||||
|
||||
+107
-5
@@ -1,13 +1,115 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module MarkdownToHtml
|
||||
LINK_REGEXP = %r{\[([^\]]+)\]\((https?://[^)]+)\)}
|
||||
TAGS = {
|
||||
'' => %w[<em> </em>],
|
||||
'*' => %w[<strong> </strong>],
|
||||
'~' => %w[<s> </s>]
|
||||
}.freeze
|
||||
|
||||
INLINE_TOKENIZER = /(\[)|(\]\(([^)]+?)\))|(?:`([^`].*?)`)|(\*\*\*|\*\*|\*|~~)/
|
||||
|
||||
ALLOWED_TAGS = %w[p br strong b em i u a].freeze
|
||||
ALLOWED_ATTRIBUTES = %w[href].freeze
|
||||
|
||||
module_function
|
||||
|
||||
def call(text)
|
||||
text.gsub(LINK_REGEXP) do
|
||||
ApplicationController.helpers.link_to(Regexp.last_match(1), Regexp.last_match(2))
|
||||
end
|
||||
def call(markdown)
|
||||
return '' if markdown.blank?
|
||||
|
||||
text = auto_link_urls(markdown)
|
||||
html = render_markdown(text)
|
||||
|
||||
ActionController::Base.helpers.sanitize(html, tags: ALLOWED_TAGS, attributes: ALLOWED_ATTRIBUTES)
|
||||
end
|
||||
|
||||
def auto_link_urls(text)
|
||||
link_parts = text.split(%r{((?:https?://|www\.)[^\s)]+)})
|
||||
|
||||
link_parts.map.with_index do |part, index|
|
||||
if part.match?(%r{\A(?:https?://|www\.)}) &&
|
||||
!link_parts[index - 1]&.match?(/\]\(\s*\z/)
|
||||
trail = part.match(/([.,;:!?]+)\z/)[1] if part.match?(/[.,;:!?]+\z/)
|
||||
clean = trail ? part.chomp(trail) : part
|
||||
url = clean.start_with?('www.') ? "http://#{clean}" : clean
|
||||
"[#{clean}](#{url})#{trail}"
|
||||
else
|
||||
part
|
||||
end
|
||||
end.join
|
||||
end
|
||||
|
||||
def render_markdown(text)
|
||||
text = text.gsub(/\+\+([^+]+)\+\+/, '<u>\1</u>')
|
||||
|
||||
paragraphs = text.split(/\n{2,}/)
|
||||
|
||||
html = paragraphs.filter_map do |para|
|
||||
content = para.strip
|
||||
|
||||
next if content.empty?
|
||||
|
||||
next '<p><br></p>' if [' ', '&nbsp;'].include?(content)
|
||||
|
||||
content = content.gsub(/ *\n/, '<br>')
|
||||
|
||||
"<p>#{parse_inline(content)}</p>"
|
||||
end.join
|
||||
|
||||
html.presence || '<p></p>'
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics
|
||||
def parse_inline(text)
|
||||
context = []
|
||||
out = ''
|
||||
last = 0
|
||||
|
||||
tag = lambda do |t|
|
||||
desc = TAGS[t[1] || '']
|
||||
return t unless desc
|
||||
return desc[0] unless desc[1]
|
||||
|
||||
is_end = context.last == t
|
||||
is_end ? context.pop : context.push(t)
|
||||
desc[is_end ? 1 : 0]
|
||||
end
|
||||
|
||||
flush = lambda do
|
||||
str = ''
|
||||
str += tag.call(context.last) while context.any?
|
||||
str
|
||||
end
|
||||
|
||||
while last <= text.length && (m = INLINE_TOKENIZER.match(text, last))
|
||||
prev = text[last...m.begin(0)]
|
||||
last = m.end(0)
|
||||
chunk = m[0]
|
||||
|
||||
if m[4]
|
||||
chunk = "<code>#{ERB::Util.html_escape(m[4])}</code>"
|
||||
elsif m[2]
|
||||
out = out.sub(/\A(.*)<a>/m, "\\1<a href=\"#{ERB::Util.html_escape(m[3])}\">")
|
||||
out = out.gsub('<a>', '[')
|
||||
chunk = "#{flush.call}</a>"
|
||||
elsif m[1]
|
||||
chunk = '<a>'
|
||||
elsif m[5]
|
||||
chunk = if m[5] == '***'
|
||||
if context.include?('*') && context.include?('**')
|
||||
tag.call('*') + tag.call('**')
|
||||
else
|
||||
tag.call('**') + tag.call('*')
|
||||
end
|
||||
else
|
||||
tag.call(m[5])
|
||||
end
|
||||
end
|
||||
|
||||
out += prev.to_s + chunk
|
||||
end
|
||||
|
||||
(out + text[last..].to_s + flush.call).gsub('<a>', '[')
|
||||
end
|
||||
# rubocop:enable Metrics
|
||||
end
|
||||
|
||||
@@ -14,6 +14,18 @@
|
||||
"@hotwired/turbo-rails": "^7.3.0",
|
||||
"@specious/htmlflow": "^1.1.0",
|
||||
"@tabler/icons-vue": "^2.47.0",
|
||||
"@tiptap/core": "^3.19.0",
|
||||
"@tiptap/extension-bold": "^3.19.0",
|
||||
"@tiptap/extension-document": "^3.19.0",
|
||||
"@tiptap/extension-hard-break": "^3.19.0",
|
||||
"@tiptap/extension-italic": "^3.19.0",
|
||||
"@tiptap/extension-link": "^3.19.0",
|
||||
"@tiptap/extension-paragraph": "^3.19.0",
|
||||
"@tiptap/extension-text": "^3.19.0",
|
||||
"@tiptap/extension-underline": "^3.19.0",
|
||||
"@tiptap/extensions": "^3.19.0",
|
||||
"@tiptap/markdown": "^3.19.0",
|
||||
"@tiptap/pm": "^3.19.0",
|
||||
"autocompleter": "^9.1.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"babel-loader": "9.1.2",
|
||||
|
||||
@@ -1743,6 +1743,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-7.0.4.tgz#70a3ca56809f7aaabb80af2f9c01ae51e1a8ed41"
|
||||
integrity sha512-tz4oM+Zn9CYsvtyicsa/AwzKZKL+ITHWkhiu7x+xF77clh2b4Rm+s6xnOgY/sGDWoFWZmtKsE95hxBPkgQQNnQ==
|
||||
|
||||
"@remirror/core-constants@3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-3.0.0.tgz#96fdb89d25c62e7b6a5d08caf0ce5114370e3b8f"
|
||||
integrity sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==
|
||||
|
||||
"@sinclair/typebox@^0.25.16":
|
||||
version "0.25.24"
|
||||
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718"
|
||||
@@ -1767,6 +1772,89 @@
|
||||
resolved "https://registry.yarnpkg.com/@tabler/icons/-/icons-2.47.0.tgz#c41c680d1947e3ab2d60af3febc4132287c60596"
|
||||
integrity sha512-4w5evLh+7FUUiA1GucvGj2ReX2TvOjEr4ejXdwL/bsjoSkof6r1gQmzqI+VHrE2CpJpB3al7bCTulOkFa/RcyA==
|
||||
|
||||
"@tiptap/core@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-3.19.0.tgz#dca483b50e1b8a596f695aecde387a79fe7da717"
|
||||
integrity sha512-bpqELwPW+DG8gWiD8iiFtSl4vIBooG5uVJod92Qxn3rA9nFatyXRr4kNbMJmOZ66ezUvmCjXVe/5/G4i5cyzKA==
|
||||
|
||||
"@tiptap/extension-bold@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-3.19.0.tgz#ef0ddfd9b242ef9c25e3348aef9bf2dc681cdc19"
|
||||
integrity sha512-UZgb1d0XK4J/JRIZ7jW+s4S6KjuEDT2z1PPM6ugcgofgJkWQvRZelCPbmtSFd3kwsD+zr9UPVgTh9YIuGQ8t+Q==
|
||||
|
||||
"@tiptap/extension-document@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-3.19.0.tgz#dfa6889cff748d489e0bc1028918bf4571372ba5"
|
||||
integrity sha512-AOf0kHKSFO0ymjVgYSYDncRXTITdTcrj1tqxVazrmO60KNl1Rc2dAggDvIVTEBy5NvceF0scc7q3sE/5ZtVV7A==
|
||||
|
||||
"@tiptap/extension-hard-break@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-3.19.0.tgz#7120524cec9ed4b957963693cb4c57cbecbaecf8"
|
||||
integrity sha512-lAmQraYhPS5hafvCl74xDB5+bLuNwBKIEsVoim35I0sDJj5nTrfhaZgMJ91VamMvT+6FF5f1dvBlxBxAWa8jew==
|
||||
|
||||
"@tiptap/extension-italic@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-3.19.0.tgz#af2a9c095ec846e379041f3e17e1dd101a5a4bf8"
|
||||
integrity sha512-6GffxOnS/tWyCbDkirWNZITiXRta9wrCmrfa4rh+v32wfaOL1RRQNyqo9qN6Wjyl1R42Js+yXTzTTzZsOaLMYA==
|
||||
|
||||
"@tiptap/extension-link@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-3.19.0.tgz#e8e656735bda6ca1d4b6577821e06274ab0ff6c8"
|
||||
integrity sha512-HEGDJnnCPfr7KWu7Dsq+eRRe/mBCsv6DuI+7fhOCLDJjjKzNgrX2abbo/zG3D/4lCVFaVb+qawgJubgqXR/Smw==
|
||||
dependencies:
|
||||
linkifyjs "^4.3.2"
|
||||
|
||||
"@tiptap/extension-paragraph@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-3.19.0.tgz#91adde189aabf13a2bfbb2d961833d3bc2bc055f"
|
||||
integrity sha512-xWa6gj82l5+AzdYyrSk9P4ynySaDzg/SlR1FarXE5yPXibYzpS95IWaVR0m2Qaz7Rrk+IiYOTGxGRxcHLOelNg==
|
||||
|
||||
"@tiptap/extension-text@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-3.19.0.tgz#353278c97bd8f5bdc29f06942fbd1e856bdb5b18"
|
||||
integrity sha512-K95+SnbZy0h6hNFtfy23n8t/nOcTFEf69In9TSFVVmwn/Nwlke+IfiESAkqbt1/7sKJeegRXYO7WzFEmFl9Q/g==
|
||||
|
||||
"@tiptap/extension-underline@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extension-underline/-/extension-underline-3.19.0.tgz#bbc81d085725981d256127ab416f91d0802ec2a4"
|
||||
integrity sha512-800MGEWfG49j10wQzAFiW/ele1HT04MamcL8iyuPNu7ZbjbGN2yknvdrJlRy7hZlzIrVkZMr/1tz62KN33VHIw==
|
||||
|
||||
"@tiptap/extensions@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/extensions/-/extensions-3.19.0.tgz#5747c0ebf460b9669e8b4362561872448f66abfe"
|
||||
integrity sha512-ZmGUhLbMWaGqnJh2Bry+6V4M6gMpUDYo4D1xNux5Gng/E/eYtc+PMxMZ/6F7tNTAuujLBOQKj6D+4SsSm457jw==
|
||||
|
||||
"@tiptap/markdown@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/markdown/-/markdown-3.19.0.tgz#dd05451b40f2a553cab0fdbb4a8714a2b2430b5c"
|
||||
integrity sha512-Pnfacq2FHky1rqwmGwEmUJxuZu8VZ8XjaJIqsQC34S3CQWiOU+PukC9In2odzcooiVncLWT9s97jKuYpbmF1tQ==
|
||||
dependencies:
|
||||
marked "^17.0.1"
|
||||
|
||||
"@tiptap/pm@^3.19.0":
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-3.19.0.tgz#5cb499c7b2603ec6550d0c7a70b924f27fdb7692"
|
||||
integrity sha512-789zcnM4a8OWzvbD2DL31d0wbSm9BVeO/R7PLQwLIGysDI3qzrcclyZ8yhqOEVuvPitRRwYLq+mY14jz7kY4cw==
|
||||
dependencies:
|
||||
prosemirror-changeset "^2.3.0"
|
||||
prosemirror-collab "^1.3.1"
|
||||
prosemirror-commands "^1.6.2"
|
||||
prosemirror-dropcursor "^1.8.1"
|
||||
prosemirror-gapcursor "^1.3.2"
|
||||
prosemirror-history "^1.4.1"
|
||||
prosemirror-inputrules "^1.4.0"
|
||||
prosemirror-keymap "^1.2.2"
|
||||
prosemirror-markdown "^1.13.1"
|
||||
prosemirror-menu "^1.2.4"
|
||||
prosemirror-model "^1.24.1"
|
||||
prosemirror-schema-basic "^1.2.3"
|
||||
prosemirror-schema-list "^1.5.0"
|
||||
prosemirror-state "^1.4.3"
|
||||
prosemirror-tables "^1.6.4"
|
||||
prosemirror-trailing-node "^3.0.0"
|
||||
prosemirror-transform "^1.10.2"
|
||||
prosemirror-view "^1.38.1"
|
||||
|
||||
"@trysound/sax@0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
|
||||
@@ -1909,6 +1997,24 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
|
||||
|
||||
"@types/linkify-it@^5":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76"
|
||||
integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==
|
||||
|
||||
"@types/markdown-it@^14.0.0":
|
||||
version "14.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.1.2.tgz#57f2532a0800067d9b934f3521429a2e8bfb4c61"
|
||||
integrity sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==
|
||||
dependencies:
|
||||
"@types/linkify-it" "^5"
|
||||
"@types/mdurl" "^2"
|
||||
|
||||
"@types/mdurl@^2":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd"
|
||||
integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==
|
||||
|
||||
"@types/mime@*":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
|
||||
@@ -2986,7 +3092,7 @@ cosmiconfig@^8.1.3:
|
||||
parse-json "^5.0.0"
|
||||
path-type "^4.0.0"
|
||||
|
||||
crelt@^1.0.5, crelt@^1.0.6:
|
||||
crelt@^1.0.0, crelt@^1.0.5, crelt@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.6.tgz#7cc898ea74e190fb6ef9dae57f8f81cf7302df72"
|
||||
integrity sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==
|
||||
@@ -4780,6 +4886,18 @@ lines-and-columns@^1.1.6:
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
||||
|
||||
linkify-it@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421"
|
||||
integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==
|
||||
dependencies:
|
||||
uc.micro "^2.0.0"
|
||||
|
||||
linkifyjs@^4.3.2:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.3.2.tgz#d97eb45419aabf97ceb4b05a7adeb7b8c8ade2b1"
|
||||
integrity sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==
|
||||
|
||||
loader-runner@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3"
|
||||
@@ -4867,6 +4985,23 @@ make-dir@^3.0.2:
|
||||
dependencies:
|
||||
semver "^6.0.0"
|
||||
|
||||
markdown-it@^14.0.0:
|
||||
version "14.1.0"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45"
|
||||
integrity sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
entities "^4.4.0"
|
||||
linkify-it "^5.0.0"
|
||||
mdurl "^2.0.0"
|
||||
punycode.js "^2.3.1"
|
||||
uc.micro "^2.1.0"
|
||||
|
||||
marked@^17.0.1:
|
||||
version "17.0.1"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-17.0.1.tgz#9db34197ac145e5929572ee49ef701e37ee9b2e6"
|
||||
integrity sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==
|
||||
|
||||
math-intrinsics@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
|
||||
@@ -4897,6 +5032,11 @@ mdn-data@2.0.30:
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc"
|
||||
integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==
|
||||
|
||||
mdurl@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0"
|
||||
integrity sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
@@ -5218,6 +5358,11 @@ optionator@^0.9.1:
|
||||
type-check "^0.4.0"
|
||||
word-wrap "^1.2.3"
|
||||
|
||||
orderedmap@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-2.1.1.tgz#61481269c44031c449915497bf5a4ad273c512d2"
|
||||
integrity sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==
|
||||
|
||||
p-limit@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
||||
@@ -5739,6 +5884,160 @@ proper-lockfile@^4.1.2:
|
||||
retry "^0.12.0"
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
prosemirror-changeset@^2.3.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-changeset/-/prosemirror-changeset-2.3.1.tgz#eee3299cfabc7a027694e9abdc4e85505e9dd5e7"
|
||||
integrity sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==
|
||||
dependencies:
|
||||
prosemirror-transform "^1.0.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.6.2:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz#d101fef85618b1be53d5b99ea17bee5600781b38"
|
||||
integrity sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==
|
||||
dependencies:
|
||||
prosemirror-model "^1.0.0"
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-transform "^1.10.2"
|
||||
|
||||
prosemirror-dropcursor@^1.8.1:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz#2ed30c4796109ddeb1cf7282372b3850528b7228"
|
||||
integrity sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==
|
||||
dependencies:
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-transform "^1.1.0"
|
||||
prosemirror-view "^1.1.0"
|
||||
|
||||
prosemirror-gapcursor@^1.3.2:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.0.tgz#e1144a83b79db7ed0ec32cd0e915a0364220af43"
|
||||
integrity sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==
|
||||
dependencies:
|
||||
prosemirror-keymap "^1.0.0"
|
||||
prosemirror-model "^1.0.0"
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-view "^1.0.0"
|
||||
|
||||
prosemirror-history@^1.0.0, prosemirror-history@^1.4.1:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.5.0.tgz#ee21fc5de85a1473e3e3752015ffd6d649a06859"
|
||||
integrity sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==
|
||||
dependencies:
|
||||
prosemirror-state "^1.2.2"
|
||||
prosemirror-transform "^1.0.0"
|
||||
prosemirror-view "^1.31.0"
|
||||
rope-sequence "^1.3.0"
|
||||
|
||||
prosemirror-inputrules@^1.4.0:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz#d2e935f6086e3801486b09222638f61dae89a570"
|
||||
integrity sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==
|
||||
dependencies:
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-transform "^1.0.0"
|
||||
|
||||
prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.2.2, prosemirror-keymap@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz#c0f6ab95f75c0b82c97e44eb6aaf29cbfc150472"
|
||||
integrity sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==
|
||||
dependencies:
|
||||
prosemirror-state "^1.0.0"
|
||||
w3c-keyname "^2.2.0"
|
||||
|
||||
prosemirror-markdown@^1.13.1:
|
||||
version "1.13.4"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.13.4.tgz#4620e6a0580cd52b5fc8e352c7e04830cd4b3048"
|
||||
integrity sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==
|
||||
dependencies:
|
||||
"@types/markdown-it" "^14.0.0"
|
||||
markdown-it "^14.0.0"
|
||||
prosemirror-model "^1.25.0"
|
||||
|
||||
prosemirror-menu@^1.2.4:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-menu/-/prosemirror-menu-1.2.5.tgz#dea00e7b623cea89f4d76963bee22d2ac2343250"
|
||||
integrity sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==
|
||||
dependencies:
|
||||
crelt "^1.0.0"
|
||||
prosemirror-commands "^1.0.0"
|
||||
prosemirror-history "^1.0.0"
|
||||
prosemirror-state "^1.0.0"
|
||||
|
||||
prosemirror-model@^1.0.0, prosemirror-model@^1.20.0, prosemirror-model@^1.21.0, prosemirror-model@^1.24.1, prosemirror-model@^1.25.0, prosemirror-model@^1.25.4:
|
||||
version "1.25.4"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.25.4.tgz#8ebfbe29ecbee9e5e2e4048c4fe8e363fcd56e7c"
|
||||
integrity sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==
|
||||
dependencies:
|
||||
orderedmap "^2.0.0"
|
||||
|
||||
prosemirror-schema-basic@^1.2.3:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz#389ce1ec09b8a30ea9bbb92c58569cb690c2d695"
|
||||
integrity sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==
|
||||
dependencies:
|
||||
prosemirror-model "^1.25.0"
|
||||
|
||||
prosemirror-schema-list@^1.5.0:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz#5869c8f749e8745c394548bb11820b0feb1e32f5"
|
||||
integrity sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==
|
||||
dependencies:
|
||||
prosemirror-model "^1.0.0"
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-transform "^1.7.3"
|
||||
|
||||
prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.4.3, prosemirror-state@^1.4.4:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.4.tgz#72b5e926f9e92dcee12b62a05fcc8a2de3bf5b39"
|
||||
integrity sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==
|
||||
dependencies:
|
||||
prosemirror-model "^1.0.0"
|
||||
prosemirror-transform "^1.0.0"
|
||||
prosemirror-view "^1.27.0"
|
||||
|
||||
prosemirror-tables@^1.6.4:
|
||||
version "1.8.5"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.8.5.tgz#104427012e5a5da1d2a38c122efee8d66bdd5104"
|
||||
integrity sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==
|
||||
dependencies:
|
||||
prosemirror-keymap "^1.2.3"
|
||||
prosemirror-model "^1.25.4"
|
||||
prosemirror-state "^1.4.4"
|
||||
prosemirror-transform "^1.10.5"
|
||||
prosemirror-view "^1.41.4"
|
||||
|
||||
prosemirror-trailing-node@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz#5bc223d4fc1e8d9145e4079ec77a932b54e19e04"
|
||||
integrity sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==
|
||||
dependencies:
|
||||
"@remirror/core-constants" "3.0.0"
|
||||
escape-string-regexp "^4.0.0"
|
||||
|
||||
prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.10.2, prosemirror-transform@^1.10.5, prosemirror-transform@^1.7.3:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.11.0.tgz#f5c5050354423dc83c6b083f6f1959ec86a3f9ba"
|
||||
integrity sha512-4I7Ce4KpygXb9bkiPS3hTEk4dSHorfRw8uI0pE8IhxlK2GXsqv5tIA7JUSxtSu7u8APVOTtbUBxTmnHIxVkIJw==
|
||||
dependencies:
|
||||
prosemirror-model "^1.21.0"
|
||||
|
||||
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.38.1, prosemirror-view@^1.41.4:
|
||||
version "1.41.5"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.41.5.tgz#3e152d14af633f2f5a73aba24e6130c63f643b2b"
|
||||
integrity sha512-UDQbIPnDrjE8tqUBbPmCOZgtd75htE6W3r0JCmY9bL6W1iemDM37MZEKC49d+tdQ0v/CKx4gjxLoLsfkD2NiZA==
|
||||
dependencies:
|
||||
prosemirror-model "^1.20.0"
|
||||
prosemirror-state "^1.0.0"
|
||||
prosemirror-transform "^1.1.0"
|
||||
|
||||
proxy-addr@~2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
|
||||
@@ -5752,6 +6051,11 @@ proxy-from-env@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
|
||||
punycode.js@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7"
|
||||
integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
|
||||
@@ -6010,6 +6314,11 @@ rollbar@^2.26.4:
|
||||
optionalDependencies:
|
||||
decache "^3.0.5"
|
||||
|
||||
rope-sequence@^1.3.0:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.4.tgz#df85711aaecd32f1e756f76e43a415171235d425"
|
||||
integrity sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==
|
||||
|
||||
run-applescript@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-7.1.0.tgz#2e9e54c4664ec3106c5b5630e249d3d6595c4911"
|
||||
@@ -6792,6 +7101,11 @@ typed-function@^4.1.1:
|
||||
resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-4.1.1.tgz#38ce3cae31f4f513bcb263563fdad27b2afa73e8"
|
||||
integrity sha512-Pq1DVubcvibmm8bYcMowjVnnMwPVMeh0DIdA8ad8NZY2sJgapANJmiigSUwlt+EgXxpfIv8MWrQXTIzkfYZLYQ==
|
||||
|
||||
uc.micro@^2.0.0, uc.micro@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee"
|
||||
integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==
|
||||
|
||||
unbox-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
|
||||
@@ -6934,7 +7248,7 @@ vue@^3.3.2:
|
||||
"@vue/server-renderer" "3.3.4"
|
||||
"@vue/shared" "3.3.4"
|
||||
|
||||
w3c-keyname@^2.2.4:
|
||||
w3c-keyname@^2.2.0, w3c-keyname@^2.2.4:
|
||||
version "2.2.8"
|
||||
resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.8.tgz#7b17c8c6883d4e8b86ac8aba79d39e880f8869c5"
|
||||
integrity sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==
|
||||
|
||||
Reference in New Issue
Block a user