diff --git a/core/editor.js b/core/editor.js index f70b523413..f3560234be 100644 --- a/core/editor.js +++ b/core/editor.js @@ -207,13 +207,13 @@ class Editor { const oldValue = mutations[0].oldValue.replace(CursorBlot.CONTENTS, ''); const oldText = new Delta().insert(oldValue); const newText = new Delta().insert(textBlot.value()); - const relativeSelectionInfo = selectionInfo && [ - new Range(selectionInfo[0].index - index, selectionInfo[0].length), - new Range(selectionInfo[1].index - index, selectionInfo[1].length), - ]; + const relativeSelectionInfo = selectionInfo && { + oldRange: shiftRange(selectionInfo.oldRange, -index), + newRange: shiftRange(selectionInfo.newRange, -index), + }; const diffDelta = new Delta() .retain(index) - .concat(diffDeltas(oldText, newText, relativeSelectionInfo)); + .concat(oldText.diff(newText, relativeSelectionInfo)); change = diffDelta.reduce((delta, op) => { if (op.insert) { return delta.insert(op.insert, formats); @@ -224,7 +224,7 @@ class Editor { } else { this.delta = this.getDelta(); if (!change || !equal(oldDelta.compose(change), this.delta)) { - change = diffDeltas(oldDelta, this.delta, selectionInfo); + change = oldDelta.diff(this.delta, selectionInfo); } } return change; @@ -339,84 +339,8 @@ function normalizeDelta(delta) { }, new Delta()); } -function splitDelta(delta, index) { - return [delta.slice(0, index), delta.slice(index)]; -} - -function diffDeltas(oldDelta, newDelta, selectionInfo = undefined) { - if (selectionInfo == null) { - return oldDelta.diff(newDelta); - } - - // generate better diffs than Delta#diff by taking into account the - // old and new selection. for example, a text change from "xxx" to "xx" - // could be a delete or forwards-delete of any one of the x's, or the - // result of selecting two of the x's and typing "x". - const [oldSelection, newSelection] = selectionInfo; - const oldDeltaLength = oldDelta.length(); - const newDeltaLength = newDelta.length(); - if (oldSelection.length === 0 && newSelection.length === 0) { - // see if we have an insert or delete before or after cursor - const oldCursor = oldSelection.index; - const newCursor = newSelection.index; - const [oldBefore, oldAfter] = splitDelta(oldDelta, oldCursor); - const [newBefore, newAfter] = splitDelta(newDelta, newCursor); - if (equal(oldAfter, newAfter)) { - const prefixLength = Math.min(oldCursor, newCursor); - const [oldPrefix, oldMiddle] = splitDelta(oldBefore, prefixLength); - const [newPrefix, newMiddle] = splitDelta(newBefore, prefixLength); - if (equal(oldPrefix, newPrefix)) { - // insert or delete right before cursor - return new Delta() - .retain(prefixLength) - .concat(oldMiddle.diff(newMiddle)); - } - } else if (equal(oldBefore, newBefore)) { - const suffixLength = Math.min( - oldDeltaLength - oldCursor, - newDeltaLength - newCursor, - ); - const [oldMiddle, oldSuffix] = splitDelta( - oldAfter, - oldDeltaLength - oldCursor - suffixLength, - ); - const [newMiddle, newSuffix] = splitDelta( - newAfter, - newDeltaLength - newCursor - suffixLength, - ); - if (equal(oldSuffix, newSuffix)) { - // insert or delete right after cursor - return new Delta().retain(oldCursor).concat(oldMiddle.diff(newMiddle)); - } - } - } - if (oldSelection.length > 0 && newSelection.length === 0) { - // see if diff could be a splice of the old selection range - const oldPrefix = oldDelta.slice(0, oldSelection.index); - const oldSuffix = oldDelta.slice(oldSelection.index + oldSelection.length); - const prefixLength = oldPrefix.length(); - const suffixLength = oldSuffix.length(); - if (newDeltaLength >= prefixLength + suffixLength) { - const newPrefix = newDelta.slice(0, prefixLength); - const newSuffix = newDelta.slice(newDeltaLength - suffixLength); - if (equal(oldPrefix, newPrefix) && equal(oldSuffix, newSuffix)) { - const oldMiddle = oldDelta.slice( - prefixLength, - oldDeltaLength - suffixLength, - ); - const newMiddle = newDelta.slice( - prefixLength, - newDeltaLength - suffixLength, - ); - return new Delta() - .retain(prefixLength) - .concat(newMiddle) - .delete(oldMiddle.length()); - } - } - } - - return oldDelta.diff(newDelta); +function shiftRange({ index, length }, amount) { + return new Range(index + amount, length); } export default Editor; diff --git a/core/quill.js b/core/quill.js index 7fc4652f81..024f64b938 100644 --- a/core/quill.js +++ b/core/quill.js @@ -105,7 +105,7 @@ class Quill { const oldRange = this.selection.lastRange; const [newRange] = this.selection.getRange(); const selectionInfo = - oldRange && newRange ? [oldRange, newRange] : undefined; + oldRange && newRange ? { oldRange, newRange } : undefined; modify.call( this, () => this.editor.update(null, mutations, selectionInfo), diff --git a/package-lock.json b/package-lock.json index b6f9544515..07a140f4d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4007,7 +4007,8 @@ "fast-diff": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", - "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==" + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==", + "dev": true }, "fast-json-stable-stringify": { "version": "2.0.0", @@ -7482,13 +7483,18 @@ "dev": true }, "quill-delta": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-4.0.1.tgz", - "integrity": "sha512-8MdJmDlsnkGTMP3VVqVb/S95l+X691/xY1iQ3tmDDBWkqUyqh72+tBnaEStxfEa5YqzozGeYWz8j2B3pni5Bew==", + "version": "4.1.0", + "resolved": "github:quilljs/delta#cc5e690e389f8f7623c8ab42341064a05c76b433", "requires": { "deep-equal": "^1.0.1", "extend": "^3.0.2", - "fast-diff": "1.1.2" + "fast-diff": "github:jhchen/fast-diff#f4e19f4486123086679ee2c8f703efb44dfb2499" + }, + "dependencies": { + "fast-diff": { + "version": "github:jhchen/fast-diff#f4e19f4486123086679ee2c8f703efb44dfb2499", + "from": "github:jhchen/fast-diff#f4e19f4486123086679ee2c8f703efb44dfb2499" + } } }, "randombytes": { diff --git a/package.json b/package.json index 4fb13d43e4..67242780c0 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "eventemitter3": "^3.1.0", "extend": "^3.0.2", "parchment": "quilljs/parchment#2674d396d363e3b4668111590426405e3754d1a0", - "quill-delta": "4.0.1" + "quill-delta": "4.1.0" }, "devDependencies": { "babel-core": "^6.26.3",