Skip to content

Commit

Permalink
fix: deep reactivity of delta
Browse files Browse the repository at this point in the history
  • Loading branch information
Tofandel committed Feb 1, 2023
1 parent f402ebb commit 88668df
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
4 changes: 3 additions & 1 deletion demo/src/examples/ContentType.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@ export default defineComponent({
]);
contentHTML.value = '<h3>This is a different HTML header</h3>';
contentText.value = 'This is some more plain text';
setTimeout(() =>
contentDelta.value.insert('\n I am also deeply reactive and a ref update works'), 200)
}
return { contentDelta, contentHTML, contentText, update }
},
})
</script>

15 changes: 10 additions & 5 deletions packages/vue-quill/src/components/QuillEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,16 @@ export const QuillEditor = defineComponent({
)
}

const maybeClone = (delta: Delta | string) => {
return typeof delta === 'object' ? delta.slice() : delta
}

const deltaHasValuesOtherThanRetain = (delta: Delta): boolean => {
return Object.values(delta.ops).some((v) => !v.retain)
}

// eslint-disable-next-line vue/no-setup-props-destructure
let internalModel = props.content // Doesn't need reactivity
// Doesn't need reactivity, but does need to be cloned to avoid deep mutations always registering as equal
let internalModel: typeof props.content
const internalModelEquals = (against: Delta | String | undefined) => {
if (typeof internalModel === typeof against) {
if (against === internalModel) {
Expand All @@ -214,7 +218,7 @@ export const QuillEditor = defineComponent({
// Quill should never be null at this point because we receive an event
// so content should not be undefined but let's make ts and eslint happy
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
internalModel = getContents()!
internalModel = maybeClone(getContents()!)
// Update v-model:content when text changes
if (!internalModelEquals(props.content)) {
ctx.emit('update:content', internalModel)
Expand Down Expand Up @@ -302,6 +306,7 @@ export const QuillEditor = defineComponent({
} else {
quill?.setContents(content as Delta, source)
}
internalModel = maybeClone(content)
}

const getText = (index?: number, length?: number): string => {
Expand Down Expand Up @@ -338,14 +343,14 @@ export const QuillEditor = defineComponent({
(newContent) => {
if (!quill || !newContent || internalModelEquals(newContent)) return

internalModel = newContent
// Restore the selection and cursor position after updating the content
const selection = quill.getSelection()
if (selection) {
nextTick(() => quill?.setSelection(selection))
}
setContents(newContent)
}
},
{ deep: true }
)

watch(
Expand Down

0 comments on commit 88668df

Please sign in to comment.