mirror of
https://github.com/john-okeefe/foliate-js.git
synced 2026-09-09 11:29:14 -04:00
66 lines
2.3 KiB
JavaScript
66 lines
2.3 KiB
JavaScript
export class Annotations {
|
|
#annotationsByIndex = new Map()
|
|
#byValue = new Map()
|
|
#anchorsByValue = new Map()
|
|
#indicesByValue = new Map()
|
|
constructor({ resolve, compare, onAdd, onDelete, onUpdate }) {
|
|
this.resolve = resolve
|
|
this.compare = compare
|
|
this.onAdd = onAdd
|
|
this.onDelete = onDelete
|
|
this.onUpdate = onUpdate
|
|
}
|
|
async add(annotation, sorted) {
|
|
const { value } = annotation
|
|
if (this.#byValue.has(value)) return
|
|
const { index, anchor } = await this.resolve(value)
|
|
this.#byValue.set(value, annotation)
|
|
this.#indicesByValue.set(value, index)
|
|
this.#anchorsByValue.set(value, anchor)
|
|
if (this.#annotationsByIndex.has(index)) {
|
|
const arr = this.#annotationsByIndex.get(index)
|
|
if (sorted) {
|
|
arr.push(annotation)
|
|
this.onAdd?.(annotation, index, arr.length - 1)
|
|
} else {
|
|
let position = 0
|
|
for (let i = 0; i < arr.length; i++) {
|
|
const itemValue = arr[i].value
|
|
if (this.compare(value, itemValue) <= 0) break
|
|
position = i + 1
|
|
}
|
|
arr.splice(position, 0, annotation)
|
|
this.onAdd?.(annotation, index, position)
|
|
}
|
|
} else {
|
|
this.#annotationsByIndex.set(index, [annotation])
|
|
this.onAdd?.(annotation, index, 0)
|
|
}
|
|
}
|
|
update(annotation) {
|
|
const index = this.#indicesByValue.get(annotation.value)
|
|
const old = this.#byValue.get(annotation.value)
|
|
Object.assign(old, annotation)
|
|
this.onUpdate?.(annotation, index)
|
|
}
|
|
delete(value) {
|
|
const index = this.#indicesByValue.get(value)
|
|
const arr = this.#annotationsByIndex.get(index)
|
|
const position = arr.findIndex(a => a.value === value)
|
|
arr.splice(position, 1)
|
|
this.#byValue.delete(value)
|
|
this.#indicesByValue.delete(value)
|
|
this.#anchorsByValue.delete(value)
|
|
this.onDelete?.(value, index, position)
|
|
}
|
|
getByIndex(index) {
|
|
return this.#annotationsByIndex.get(index) ?? []
|
|
}
|
|
getAnchor(value) {
|
|
return this.#anchorsByValue.get(value)
|
|
}
|
|
export() {
|
|
return Array.from(this.#annotationsByIndex.values()).flat()
|
|
}
|
|
}
|