Skip to content

Commit dc589e1

Browse files
authoredFeb 4, 2023
Merge pull request #317 from Tofandel/master
fix: delta comparison
2 parents 545cfa4 + f96121b commit dc589e1

File tree

3 files changed

+17
-16
lines changed

3 files changed

+17
-16
lines changed
 

‎demo/src/examples/BasicExample.vue

+1-6
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,10 @@ export default defineComponent({
1313
},
1414
setup: () => {
1515
const content = ref<Delta>(
16-
new Delta([
17-
{ insert: 'Gandalf', attributes: { bold: true } },
18-
{ insert: ' the ' },
19-
{ insert: 'Grey', attributes: { color: '#ccc' } },
20-
])
16+
new Delta()
2117
)
2218
2319
return { content }
2420
},
2521
})
2622
</script>
27-

‎demo/src/examples/ContentType.vue

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ export default defineComponent({
5050
]);
5151
contentHTML.value = '<h3>This is a different HTML header</h3>';
5252
contentText.value = 'This is some more plain text';
53+
54+
setTimeout(() =>
55+
contentDelta.value.insert('\n I am also deeply reactive and a ref update works'), 200)
5356
}
5457
5558
return { contentDelta, contentHTML, contentText, update }
5659
},
5760
})
5861
</script>
59-

‎packages/vue-quill/src/components/QuillEditor.ts

+13-9
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,18 @@ export const QuillEditor = defineComponent({
185185
)
186186
}
187187

188+
const maybeClone = (delta: Delta | string) => {
189+
return typeof delta === 'object' ? delta.slice() : delta
190+
}
191+
188192
const deltaHasValuesOtherThanRetain = (delta: Delta): boolean => {
189-
return Object.values(delta).some((v) => !v.retain)
193+
return Object.values(delta.ops).some(
194+
(v) => !v.retain || Object.keys(v).length !== 1
195+
)
190196
}
191197

192-
// eslint-disable-next-line vue/no-setup-props-destructure
193-
let internalModel = props.content // Doesn't need reactivity
198+
// Doesn't need reactivity, but does need to be cloned to avoid deep mutations always registering as equal
199+
let internalModel: typeof props.content
194200
const internalModelEquals = (against: Delta | String | undefined) => {
195201
if (typeof internalModel === typeof against) {
196202
if (against === internalModel) {
@@ -211,10 +217,7 @@ export const QuillEditor = defineComponent({
211217
oldContents: Delta,
212218
source: Sources
213219
) => {
214-
// Quill should never be null at this point because we receive an event
215-
// so content should not be undefined but let's make ts and eslint happy
216-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
217-
internalModel = getContents()!
220+
internalModel = maybeClone(getContents() as string | Delta)
218221
// Update v-model:content when text changes
219222
if (!internalModelEquals(props.content)) {
220223
ctx.emit('update:content', internalModel)
@@ -302,6 +305,7 @@ export const QuillEditor = defineComponent({
302305
} else {
303306
quill?.setContents(content as Delta, source)
304307
}
308+
internalModel = maybeClone(content)
305309
}
306310

307311
const getText = (index?: number, length?: number): string => {
@@ -338,14 +342,14 @@ export const QuillEditor = defineComponent({
338342
(newContent) => {
339343
if (!quill || !newContent || internalModelEquals(newContent)) return
340344

341-
internalModel = newContent
342345
// Restore the selection and cursor position after updating the content
343346
const selection = quill.getSelection()
344347
if (selection) {
345348
nextTick(() => quill?.setSelection(selection))
346349
}
347350
setContents(newContent)
348-
}
351+
},
352+
{ deep: true }
349353
)
350354

351355
watch(

0 commit comments

Comments
 (0)
Please sign in to comment.