Skip to content

Commit

Permalink
fix(core): allow insertContentAt and insertContent text node arrays (#…
Browse files Browse the repository at this point in the history
…3790)

* fix(core): allow insertContentAt and insertContent to handle array of text nodes

* fix(core): allow insertContent via json including a text content
  • Loading branch information
bdbch committed Feb 27, 2023
1 parent 1ac3070 commit 0300630
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 1 deletion.
Empty file.
11 changes: 11 additions & 0 deletions demos/src/Commands/InsertContent/Vue/index.spec.js
@@ -0,0 +1,11 @@
context('/src/Commands/InsertContent/Vue/', () => {
before(() => {
cy.visit('/src/Commands/InsertContent/Vue/')
})

beforeEach(() => {
cy.get('.ProseMirror').then(([{ editor }]) => {
editor.commands.clearContent()
})
})
})
102 changes: 102 additions & 0 deletions demos/src/Commands/InsertContent/Vue/index.vue
@@ -0,0 +1,102 @@
<template>
<div v-if="editor">
<button @click="insertContentByString">Insert content by string</button>
<button @click="insertContentByJSON">Insert content by JSON</button>
<button @click="insertTextByJSON">Insert text by JSON</button>
<button @click="insertTextByJSONArray">Insert text by JSON Array</button>
</div>
<editor-content :editor="editor" />
</template>

<script>
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { Editor, EditorContent } from '@tiptap/vue-3'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
],
content: `
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. That’s it. It’s probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`,
})
},
beforeUnmount() {
this.editor.destroy()
},
methods: {
insertContentByString() {
this.editor.chain().focus().insertContent('<p>Hello World</p>').run()
},
insertContentByJSON() {
this.editor.chain().focus().insertContent({
type: 'paragraph',
content: [
{
type: 'text',
text: 'Hello',
},
{
type: 'text',
text: ' ',
},
{
type: 'text',
text: 'World',
},
],
}).run()
},
insertTextByJSON() {
this.editor.chain().focus().insertContent({
type: 'text',
text: 'Hello World',
}).run()
},
insertTextByJSONArray() {
this.editor.chain().focus().insertContent([{
type: 'text',
text: 'Hello',
}, {
type: 'text',
text: ' ',
}, {
type: 'text',
text: 'World',
}]).run()
},
},
}
</script>

<style lang="scss">
/* Basic editor styles */
.ProseMirror {
> * + * {
margin-top: 0.75em;
}
}
</style>
10 changes: 9 additions & 1 deletion packages/core/src/commands/insertContentAt.ts
Expand Up @@ -79,7 +79,15 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
// if there is only plain text we have to use `insertText`
// because this will keep the current marks
if (isOnlyTextContent) {
tr.insertText(value as string, from, to)
// if value is string, we can use it directly
// otherwise if it is an array, we have to join it
if (Array.isArray(value)) {
tr.insertText(value.map(v => v.text || '').join(''), from, to)
} else if (typeof value === 'object' && !!value && !!value.text) {
tr.insertText(value.text, from, to)
} else {
tr.insertText(value as string, from, to)
}
} else {
tr.replaceWith(from, to, content)
}
Expand Down

0 comments on commit 0300630

Please sign in to comment.