Files
yjs/src/Struct/Delete.js

85 lines
2.5 KiB
JavaScript
Raw Normal View History

2017-10-16 04:53:12 +02:00
import { getReference } from '../Util/structReferences.js'
import ID from '../Util/ID.js'
2017-10-26 19:12:33 +02:00
import { logID } from '../MessageHandler/messageToString.js'
2017-10-11 03:41:54 +02:00
/**
* Delete all items in an ID-range
* TODO: implement getItemCleanStartNode for better performance (only one lookup)
*/
2017-10-16 04:53:12 +02:00
export function deleteItemRange (y, user, clock, range) {
2017-12-24 03:18:00 +01:00
const createDelete = y.connector !== null && y.connector._forwardAppliedStructs
let item = y.os.getItemCleanStart(new ID(user, clock))
if (item !== null) {
if (!item._deleted) {
item._splitAt(y, range)
item._delete(y, createDelete)
}
let itemLen = item._length
range -= itemLen
clock += itemLen
if (range > 0) {
let node = y.os.findNode(new ID(user, clock))
while (node !== null && range > 0 && node.val._id.equals(new ID(user, clock))) {
const nodeVal = node.val
if (!nodeVal._deleted) {
nodeVal._splitAt(y, range)
nodeVal._delete(y, createDelete)
}
const nodeLen = nodeVal._length
range -= nodeLen
clock += nodeLen
node = node.next()
}
}
2017-10-16 04:53:12 +02:00
}
}
/**
* Delete is not a real struct. It will not be saved in OS
*/
2017-10-11 03:41:54 +02:00
export default class Delete {
constructor () {
2017-10-26 20:53:17 +02:00
this._target = null
2017-10-11 03:41:54 +02:00
this._length = null
}
_fromBinary (y, decoder) {
2017-10-26 19:12:33 +02:00
// TODO: set target, and add it to missing if not found
// There is an edge case in p2p networks!
2017-10-26 20:53:17 +02:00
const targetID = decoder.readID()
this._targetID = targetID
2017-10-11 03:41:54 +02:00
this._length = decoder.readVarUint()
2017-10-26 20:53:17 +02:00
if (y.os.getItem(targetID) === null) {
return [targetID]
} else {
return []
}
2017-10-11 03:41:54 +02:00
}
2017-10-16 04:53:12 +02:00
_toBinary (encoder) {
encoder.writeUint8(getReference(this.constructor))
encoder.writeID(this._targetID)
2017-10-11 03:41:54 +02:00
encoder.writeVarUint(this._length)
}
2017-10-16 04:53:12 +02:00
/**
* - If created remotely (a remote user deleted something),
* this Delete is applied to all structs in id-range.
* - If created lokally (e.g. when y-array deletes a range of elements),
* this struct is broadcasted only (it is already executed)
*/
_integrate (y, locallyCreated = false) {
if (!locallyCreated) {
// from remote
const id = this._targetID
deleteItemRange(y, id.user, id.clock, this._length)
2017-12-24 03:18:00 +01:00
} else if (y.connector !== null) {
2017-10-16 04:53:12 +02:00
// from local
y.connector.broadcastStruct(this)
2017-10-11 03:41:54 +02:00
}
if (y.persistence !== null) {
2017-12-24 03:18:00 +01:00
y.persistence.saveStruct(y, this)
2017-10-11 03:41:54 +02:00
}
}
_logString () {
2017-10-26 19:12:33 +02:00
return `Delete - target: ${logID(this._targetID)}, len: ${this._length}`
2017-10-11 03:41:54 +02:00
}
}