172 lines
4.1 KiB
JavaScript
172 lines
4.1 KiB
JavaScript
/**
|
|
* @module structs
|
|
*/
|
|
|
|
import {
|
|
AbstractItem,
|
|
AbstractItemRef,
|
|
computeItemParams,
|
|
readYArray,
|
|
readYMap,
|
|
readYText,
|
|
readYXmlElement,
|
|
readYXmlFragment,
|
|
readYXmlHook,
|
|
readYXmlText,
|
|
StructStore, Y, GC, Transaction, ID, AbstractType // eslint-disable-line
|
|
} from '../internals.js'
|
|
|
|
import * as encoding from 'lib0/encoding.js' // eslint-disable-line
|
|
import * as decoding from 'lib0/decoding.js'
|
|
|
|
export const structTypeRefNumber = 7
|
|
|
|
/**
|
|
* @type {Array<function(decoding.Decoder):AbstractType<any>>}
|
|
*/
|
|
export const typeRefs = [
|
|
readYArray,
|
|
readYMap,
|
|
readYText,
|
|
readYXmlElement,
|
|
readYXmlFragment,
|
|
readYXmlHook,
|
|
readYXmlText
|
|
]
|
|
|
|
export const YArrayRefID = 0
|
|
export const YMapRefID = 1
|
|
export const YTextRefID = 2
|
|
export const YXmlElementRefID = 3
|
|
export const YXmlFragmentRefID = 4
|
|
export const YXmlHookRefID = 5
|
|
export const YXmlTextRefID = 6
|
|
|
|
export class ItemType extends AbstractItem {
|
|
/**
|
|
* @param {ID} id
|
|
* @param {AbstractItem | null} left
|
|
* @param {ID | null} origin
|
|
* @param {AbstractItem | null} right
|
|
* @param {ID | null} rightOrigin
|
|
* @param {AbstractType<any>} parent
|
|
* @param {string | null} parentSub
|
|
* @param {AbstractType<any>} type
|
|
*/
|
|
constructor (id, left, origin, right, rightOrigin, parent, parentSub, type) {
|
|
super(id, left, origin, right, rightOrigin, parent, parentSub)
|
|
this.type = type
|
|
}
|
|
|
|
getContent () {
|
|
return [this.type]
|
|
}
|
|
/**
|
|
* @param {ID} id
|
|
* @param {AbstractItem | null} left
|
|
* @param {ID | null} origin
|
|
* @param {AbstractItem | null} right
|
|
* @param {ID | null} rightOrigin
|
|
* @param {AbstractType<any>} parent
|
|
* @param {string | null} parentSub
|
|
* @return {ItemType}
|
|
*/
|
|
copy (id, left, origin, right, rightOrigin, parent, parentSub) {
|
|
return new ItemType(id, left, origin, right, rightOrigin, parent, parentSub, this.type._copy())
|
|
}
|
|
/**
|
|
* @param {Transaction} transaction
|
|
*/
|
|
integrate (transaction) {
|
|
super.integrate(transaction)
|
|
this.type._integrate(transaction.y, this)
|
|
}
|
|
/**
|
|
* @param {encoding.Encoder} encoder
|
|
* @param {number} offset
|
|
*/
|
|
write (encoder, offset) {
|
|
super.write(encoder, offset, structTypeRefNumber)
|
|
this.type._write(encoder)
|
|
}
|
|
/**
|
|
* Mark this Item as deleted.
|
|
*
|
|
* @param {Transaction} transaction The Yjs instance
|
|
* @private
|
|
*/
|
|
delete (transaction) {
|
|
super.delete(transaction)
|
|
transaction.changed.delete(this.type)
|
|
transaction.changedParentTypes.delete(this.type)
|
|
this.gcChildren(transaction, transaction.y.store)
|
|
}
|
|
|
|
/**
|
|
* @param {Transaction} transaction
|
|
* @param {StructStore} store
|
|
*/
|
|
gcChildren (transaction, store) {
|
|
let item = this.type._start
|
|
while (item !== null) {
|
|
item.gc(transaction, store)
|
|
item = item.right
|
|
}
|
|
this.type._start = null
|
|
this.type._map.forEach(item => {
|
|
while (item !== null) {
|
|
item.gc(transaction, store)
|
|
// @ts-ignore
|
|
item = item.left
|
|
}
|
|
})
|
|
this._map = new Map()
|
|
}
|
|
|
|
/**
|
|
* @param {Transaction} transaction
|
|
* @param {StructStore} store
|
|
*/
|
|
gc (transaction, store) {
|
|
super.gc(transaction, store)
|
|
this.gcChildren(transaction, store)
|
|
}
|
|
}
|
|
|
|
export class ItemTypeRef extends AbstractItemRef {
|
|
/**
|
|
* @param {decoding.Decoder} decoder
|
|
* @param {ID} id
|
|
* @param {number} info
|
|
*/
|
|
constructor (decoder, id, info) {
|
|
super(decoder, id, info)
|
|
const typeRef = decoding.readVarUint(decoder)
|
|
/**
|
|
* @type {AbstractType<any>}
|
|
*/
|
|
this.type = typeRefs[typeRef](decoder)
|
|
}
|
|
/**
|
|
* @param {Transaction} transaction
|
|
* @param {StructStore} store
|
|
* @param {number} offset
|
|
* @return {ItemType|GC}
|
|
*/
|
|
toStruct (transaction, store, offset) {
|
|
const { left, right, parent, parentSub } = computeItemParams(transaction, store, this.left, this.right, this.parent, this.parentSub, this.parentYKey)
|
|
return parent === null
|
|
? new GC(this.id, this.length)
|
|
: new ItemType(
|
|
this.id,
|
|
left,
|
|
this.left,
|
|
right,
|
|
this.right,
|
|
parent,
|
|
parentSub,
|
|
this.type
|
|
)
|
|
}
|
|
}
|