json-joy
Version:
Collection of libraries for building collaborative editing apps.
75 lines (74 loc) • 2.65 kB
JavaScript
import { isEmpty } from '@jsonjoy.com/util/lib/isEmpty';
import { deepEqual } from '@jsonjoy.com/util/lib/json-equal/deepEqual';
import { Peritext } from '../peritext';
import { ExtensionId } from '../constants';
import { MNEMONIC, QuillConst } from './constants';
import { ExtNode } from '../../json-crdt/extensions/ExtNode';
import { getAttributes } from './util';
import { updateRga } from '../../json-crdt/hash';
export class QuillDeltaNode extends ExtNode {
data;
txt;
constructor(data) {
super(data);
this.data = data;
this.txt = new Peritext(data.doc, this.text(), this.slices());
}
text() {
return this.data.get(0);
}
slices() {
return this.data.get(1);
}
// ------------------------------------------------------------------ ExtNode
extId = ExtensionId.quill;
name() {
return MNEMONIC;
}
_view = [];
_viewHash = -1;
view() {
const overlay = this.txt.overlay;
const hash = updateRga(overlay.refresh(true), this.txt.str);
if (hash === this._viewHash)
return this._view;
const ops = [];
let chunk;
const nextTuple = overlay.tuples0(undefined);
let tuple;
while ((tuple = nextTuple())) {
const [p1, p2] = tuple;
const attributes = getAttributes(p1);
let insert = '';
chunk = overlay.chunkSlices0(chunk, p1, p2, (chunk, off, len) => {
const data = chunk.data;
if (data)
insert += data.slice(off, off + len);
});
if (insert) {
if (insert === QuillConst.EmbedChar && attributes && attributes[QuillConst.EmbedSliceType]) {
const op = { insert: attributes[QuillConst.EmbedSliceType] };
delete attributes[QuillConst.EmbedSliceType];
if (!isEmpty(attributes))
op.attributes = attributes;
ops.push(op);
continue;
}
else {
const lastOp = ops[ops.length - 1];
if (lastOp && typeof lastOp.insert === 'string' && deepEqual(lastOp.attributes, attributes)) {
lastOp.insert += insert;
continue;
}
}
const op = { insert };
if (attributes)
op.attributes = attributes;
ops.push(op);
}
}
this._viewHash = hash;
this._view = ops;
return ops;
}
}