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.
*/
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

View File

@ -360,7 +360,7 @@ export const compareDS = (ds1, ds2) => {
/**
* @template T
* @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 {InitTestObjectCallback<T>} [initTestObject]
*/

View File

@ -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)
}