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.
This commit is contained in:
Kevin Jahns 2019-05-19 20:40:11 +02:00
parent 4d12a02e2f
commit 72e470c5f0
3 changed files with 38 additions and 25 deletions

View File

@ -388,7 +388,7 @@ const deleteText = (transaction, left, right, currentAttributes, length) => {
/** /**
* Event that describes the changes on a YText type. * Event that describes the changes on a YText type.
*/ */
class YTextEvent extends YEvent { export class YTextEvent extends YEvent {
/** /**
* @param {YText} ytext * @param {YText} ytext
* @param {Transaction} transaction * @param {Transaction} transaction
@ -475,11 +475,13 @@ class YTextEvent extends YEvent {
switch (item.constructor) { switch (item.constructor) {
case ItemEmbed: case ItemEmbed:
if (this.adds(item)) { if (this.adds(item)) {
addOp() if (!this.deletes(item)) {
action = 'insert' addOp()
// @ts-ignore item is ItemFormat action = 'insert'
insert = item.embed // @ts-ignore item is ItemFormat
addOp() insert = item.embed
addOp()
}
} else if (this.deletes(item)) { } else if (this.deletes(item)) {
if (action !== 'delete') { if (action !== 'delete') {
addOp() addOp()
@ -496,12 +498,14 @@ class YTextEvent extends YEvent {
break break
case ItemString: case ItemString:
if (this.adds(item)) { if (this.adds(item)) {
if (action !== 'insert') { if (!this.deletes(item)) {
addOp() if (action !== 'insert') {
action = 'insert' addOp()
action = 'insert'
}
// @ts-ignore
insert += item.string
} }
// @ts-ignore
insert += item.string
} else if (this.deletes(item)) { } else if (this.deletes(item)) {
if (action !== 'delete') { if (action !== 'delete') {
addOp() addOp()
@ -518,23 +522,25 @@ class YTextEvent extends YEvent {
break break
case ItemFormat: case ItemFormat:
if (this.adds(item)) { if (this.adds(item)) {
// @ts-ignore item is ItemFormat if (!this.deletes(item)) {
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 // @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 // @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 { } else {
// @ts-ignore item is ItemFormat item.delete(transaction)
attributes[item.key] = item.value
} }
} else {
item.delete(transaction)
} }
} else if (this.deletes(item)) { } else if (this.deletes(item)) {
// @ts-ignore item is ItemFormat // @ts-ignore item is ItemFormat

View File

@ -360,7 +360,7 @@ export const compareDS = (ds1, ds2) => {
/** /**
* @template T * @template T
* @param {t.TestCase} tc * @param {t.TestCase} tc
* @param {Array<function(TestYInstance,prng.PRNG,T):void>} mods * @param {Array<function(Y.Doc,prng.PRNG,T):void>} mods
* @param {number} iterations * @param {number} iterations
* @param {InitTestObjectCallback<T>} [initTestObject] * @param {InitTestObjectCallback<T>} [initTestObject]
*/ */

View File

@ -27,6 +27,13 @@ export const testBasicInsertAndDelete = tc => {
text0.delete(1, 1) text0.delete(1, 1)
t.assert(text0.toString() === 'b', 'Basic delete works (position 1)') t.assert(text0.toString() === 'b', 'Basic delete works (position 1)')
t.compare(delta, [{ retain: 1 }, { delete: 1 }]) t.compare(delta, [{ retain: 1 }, { delete: 1 }])
users[0].transact(() => {
text0.insert(0, '1')
text0.delete(0, 1)
})
t.compare(delta, [])
compare(users) compare(users)
} }