From 72e470c5f084c6c0531e1ba7764d1511acc8c6a9 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Sun, 19 May 2019 20:40:11 +0200 Subject: [PATCH] Fix ytext event.delta - items that are synced and deleted When items are added and deleted in the same transaction, event.delta would recognize them as added (though they are actually deleted). Now it just ignores them. --- src/types/YText.js | 54 ++++++++++++++++++++++++------------------- tests/testHelper.js | 2 +- tests/y-text.tests.js | 7 ++++++ 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/types/YText.js b/src/types/YText.js index 27665ca7..bca13d00 100644 --- a/src/types/YText.js +++ b/src/types/YText.js @@ -388,7 +388,7 @@ const deleteText = (transaction, left, right, currentAttributes, length) => { /** * Event that describes the changes on a YText type. */ -class YTextEvent extends YEvent { +export class YTextEvent extends YEvent { /** * @param {YText} ytext * @param {Transaction} transaction @@ -475,11 +475,13 @@ class YTextEvent extends YEvent { switch (item.constructor) { case ItemEmbed: if (this.adds(item)) { - addOp() - action = 'insert' - // @ts-ignore item is ItemFormat - insert = item.embed - addOp() + if (!this.deletes(item)) { + addOp() + action = 'insert' + // @ts-ignore item is ItemFormat + insert = item.embed + addOp() + } } else if (this.deletes(item)) { if (action !== 'delete') { addOp() @@ -496,12 +498,14 @@ class YTextEvent extends YEvent { break case ItemString: if (this.adds(item)) { - if (action !== 'insert') { - addOp() - action = 'insert' + if (!this.deletes(item)) { + if (action !== 'insert') { + addOp() + action = 'insert' + } + // @ts-ignore + insert += item.string } - // @ts-ignore - insert += item.string } else if (this.deletes(item)) { if (action !== 'delete') { addOp() @@ -518,23 +522,25 @@ class YTextEvent extends YEvent { break case ItemFormat: if (this.adds(item)) { - // @ts-ignore item is ItemFormat - const curVal = currentAttributes.get(item.key) || null - // @ts-ignore item is ItemFormat - if (curVal !== item.value) { - if (action === 'retain') { - addOp() - } + if (!this.deletes(item)) { // @ts-ignore item is ItemFormat - if (item.value === (oldAttributes.get(item.key) || null)) { + const curVal = currentAttributes.get(item.key) || null + // @ts-ignore item is ItemFormat + if (curVal !== item.value) { + if (action === 'retain') { + addOp() + } // @ts-ignore item is ItemFormat - delete attributes[item.key] + if (item.value === (oldAttributes.get(item.key) || null)) { + // @ts-ignore item is ItemFormat + delete attributes[item.key] + } else { + // @ts-ignore item is ItemFormat + attributes[item.key] = item.value + } } else { - // @ts-ignore item is ItemFormat - attributes[item.key] = item.value + item.delete(transaction) } - } else { - item.delete(transaction) } } else if (this.deletes(item)) { // @ts-ignore item is ItemFormat diff --git a/tests/testHelper.js b/tests/testHelper.js index 41fbc07b..bf83e5b1 100644 --- a/tests/testHelper.js +++ b/tests/testHelper.js @@ -360,7 +360,7 @@ export const compareDS = (ds1, ds2) => { /** * @template T * @param {t.TestCase} tc - * @param {Array} mods + * @param {Array} mods * @param {number} iterations * @param {InitTestObjectCallback} [initTestObject] */ diff --git a/tests/y-text.tests.js b/tests/y-text.tests.js index 4e86b6d8..30bb2109 100644 --- a/tests/y-text.tests.js +++ b/tests/y-text.tests.js @@ -27,6 +27,13 @@ export const testBasicInsertAndDelete = tc => { text0.delete(1, 1) t.assert(text0.toString() === 'b', 'Basic delete works (position 1)') t.compare(delta, [{ retain: 1 }, { delete: 1 }]) + + users[0].transact(() => { + text0.insert(0, '1') + text0.delete(0, 1) + }) + t.compare(delta, []) + compare(users) }