diff --git a/core/editor.js b/core/editor.js index e018027cac..b229be56da 100644 --- a/core/editor.js +++ b/core/editor.js @@ -9,6 +9,7 @@ import Block, { BlockEmbed, bubbleFormats } from '../blots/block'; import Break from '../blots/break'; import TextBlot, { escapeText } from '../blots/text'; import removeClass from '../utils/remove_class'; +import isDefined from '../utils/is_defined'; const ASCII = /^[ -~]*$/; @@ -243,11 +244,18 @@ class Editor { } else { this.delta = this.getDelta(); if (!change || !isEqual(oldDelta.compose(change), this.delta)) { - change = oldDelta.diff(this.delta, selectionInfo); + if (!this.deltaContainsRetain(oldDelta)) { + change = oldDelta.diff(this.delta, selectionInfo); + } } } return change; } + + // T1200561 + deltaContainsRetain(delta) { + return delta.ops.some((op) => isDefined(op.retain)); + } } function convertListHTML(items, lastIndent, types) { diff --git a/test/unit/core/editor.js b/test/unit/core/editor.js index ae1c8bb5df..8b5b737659 100644 --- a/test/unit/core/editor.js +++ b/test/unit/core/editor.js @@ -295,6 +295,61 @@ describe('Editor', function () { }); }); + // T1200561 + describe('deltaContainsRetain functionality', function () { + it('delta should be empty when deltaContainsRetain returns false(T1200561)', function () { + const editor = this.initialize(Editor, '
'); + + editor.deltaContainsRetain = () => { + return false; + }; + + const sourceDelta = new Delta().insert('123'); + editor.update(sourceDelta); + + const newDelta = new Delta().insert('new string'); + + const resultDelta = editor.update(newDelta); + + expect(resultDelta.ops.length).toEqual(0); + }); + + it('delta should be empty when deltaContainsRetain returns true(T1200561)', function () { + const editor = this.initialize(Editor, ''); + + editor.deltaContainsRetain = () => { + return true; + }; + + const sourceDelta = new Delta().insert('123'); + editor.update(sourceDelta); + + const newDelta = new Delta().insert('new string'); + + const resultDelta = editor.update(newDelta); + + expect(resultDelta.ops.length).toEqual(1); + }); + + it('deltaContainsRetain should return true when delta contains retain operation(T1200561)', function () { + const editor = this.initialize(Editor, ''); + const delta = new Delta().retain(3); + + const deltaContainsRetain = editor.deltaContainsRetain(delta); + + expect(deltaContainsRetain).toEqual(true); + }); + + it('deltaContainsRetain should return false when delta not contains retain operation(T1200561)', function () { + const editor = this.initialize(Editor, ''); + const delta = new Delta().insert('123'); + + const deltaContainsRetain = editor.deltaContainsRetain(delta); + + expect(deltaContainsRetain).toEqual(false); + }); + }); + describe('applyDelta', function () { it('insert', function () { const editor = this.initialize(Editor, '');