we use the rich text editor of TipTap in our project.
But we have the problem, that spaces are not recognized correctly and only after every 2 click a space is created. As framework we use Vue.JS.
import { Editor, EditorContent, EditorMenuBar } from 'tiptap'
import {
HardBreak,
Heading,
OrderedList,
BulletList,
ListItem,
Bold,
Italic,
History
} from 'tiptap-extensions'
import EditorMenuButton from './EditorMenuButton.vue'
export default {
name: 'editor',
ponents: {
EditorMenuButton,
EditorMenuBar,
EditorContent
},
props: {
value: {
type: null,
default: ' '
}
},
data () {
return {
innerValue: ' ',
editor: new Editor({
extensions: [
new HardBreak(),
new Heading({ levels: [1, 2, 3] }),
new BulletList(),
new OrderedList(),
new ListItem(),
new Bold(),
new Italic(),
new History()
],
content: `${this.innerValue}`,
onUpdate: ({ getHTML }) => {
this.innerValue = getHTML()
}
})
}
},
watch: {
// Handles internal model changes.
innerValue (newVal) {
this.$emit('input', newVal)
},
// Handles external model changes.
value (newVal) {
this.innerValue = newVal
this.editor.setContent(this.innerValue)
}
},
mounted () {
if (this.value) {
this.innerValue = this.value
this.editor.setContent(this.innerValue)
}
},
beforeDestroy () {
this.editor.destroy()
}
}
</script>
does anyone have any idea what could be the reason for assuming only every two spaces?
we use the rich text editor of TipTap in our project.
But we have the problem, that spaces are not recognized correctly and only after every 2 click a space is created. As framework we use Vue.JS.
import { Editor, EditorContent, EditorMenuBar } from 'tiptap'
import {
HardBreak,
Heading,
OrderedList,
BulletList,
ListItem,
Bold,
Italic,
History
} from 'tiptap-extensions'
import EditorMenuButton from './EditorMenuButton.vue'
export default {
name: 'editor',
ponents: {
EditorMenuButton,
EditorMenuBar,
EditorContent
},
props: {
value: {
type: null,
default: ' '
}
},
data () {
return {
innerValue: ' ',
editor: new Editor({
extensions: [
new HardBreak(),
new Heading({ levels: [1, 2, 3] }),
new BulletList(),
new OrderedList(),
new ListItem(),
new Bold(),
new Italic(),
new History()
],
content: `${this.innerValue}`,
onUpdate: ({ getHTML }) => {
this.innerValue = getHTML()
}
})
}
},
watch: {
// Handles internal model changes.
innerValue (newVal) {
this.$emit('input', newVal)
},
// Handles external model changes.
value (newVal) {
this.innerValue = newVal
this.editor.setContent(this.innerValue)
}
},
mounted () {
if (this.value) {
this.innerValue = this.value
this.editor.setContent(this.innerValue)
}
},
beforeDestroy () {
this.editor.destroy()
}
}
</script>
does anyone have any idea what could be the reason for assuming only every two spaces?
Share Improve this question edited May 12, 2020 at 13:01 Tschallacka 28.7k15 gold badges98 silver badges138 bronze badges asked May 12, 2020 at 13:00 Jonas DegenerJonas Degener 811 silver badge4 bronze badges 6-
3
Your chances of getting a useful answer without a minimal reproducible example (actually reproducing the behavior) are close to
null
. Use codesandbox.io or any other online multi-file node based editor. What you've shown here does not reproduce the described behavior and is missing: the template and the contents ofEditorMenuButton.vue
(most likely where your bug is ing from). – tao Commented May 18, 2020 at 8:47 -
Here's a sandbox with what you've shown so far. As you can see, it's working as expected. So, please, add the bug to it so someone could debug it. :) Note: I did make some changes, because you can't init the editor in
data
. Do it inmounted
, as in their examples. Here's why. – tao Commented May 18, 2020 at 9:33 - thank you we will try to program it in the code sandbox – Jonas Degener Commented May 18, 2020 at 11:41
-
@tao initializing the editor in
data
is exactly how it's written in the examples. – Erich Commented Dec 7, 2020 at 20:30 -
@Erich, with the notable difference in the linked example it's not using
this
insidedata
. Because it's not available. Which is why I suggested moving it inmounted
. – tao Commented Dec 8, 2020 at 1:33
7 Answers
Reset to default 4We had the same problem, we kept the onUpdate
trigger but changed the watch so that it would only invoke editor.setContent
when the value was actually different.
watch: {
value() {
let html = this.editor.getHTML();
if (html !== this.value) {
this.editor.setContent(this.value);
}
},
},
Remove onUpdate section and the bug will disapear. I don't know why, but it's interesting to know how to reproduce the bug.
That does help. Following this advice, I am currently using the onBlur
event instead of onUpdate
, while obtaining the content's HTML using the editor instance and the getHTML()
function, as such: this.editor.getHTML()
.
(In my case I $emit
this value in order for it to be reactive to my parent ponent, but that may be irrelevant for the original question).
"Okay the problem is that the watcher will get fired when you type in the editor. So this will check if the editor has focus an will only update the editor content if that's not the case."
watch: {
value(val) {
if (!this.editor.focused) {
this.editor.setContent(val, false);
}
}
},
issue: https://github./ueberdosis/tiptap/issues/776#issuement-667077233
This bug for me was caused by doing something like this:
watch: {
value: {
immediate: true,
handler(newValue) {
this.editor.setContent(newValue)
},
},
},
Removed this entirely and the bug went away. Maybe this will help someone in future.
Maybe you should try this.
watch: {
// Handles external model changes.
value (newVal) {
// convert whitespace into \u00a0 ->
let content = newVal.replace(/\s/g, "\u00a0");
this.editor.setContent(content)
}
},
It seems like the normal white space has been removed by html automatically. Therefore, I convert whitespace into 'nbsp;' and it's worked.
The code you provided seems to be working just fine. So the issue most likely is produced by a side effect in either your code or some dependency.
To debug this issue you could look for event listeners, especially regarding key press or key down events and looking if you are checking for space key specifically somewhere (event.keyCode === 32
or event.key === " "
). In conjunction with event.preventDefault
this could explain such an issue.
Another more broad way to debug this is to strip away parts from your code until the bug disappears or add to a minimal example until the bug appears.
Remove onUpdate section and the bug will disapear. I don't know why, but it's interessing to know how to reproduce the bug. However if you create a "minimal reproductible example" the bug does not appear. So what ? I don't know.
I found a workaround which is to use vuex.
Rather than assign the value returned by getHTML() in the innerValue variable and then issue an 'input' event, I put this value in the store.