json-joy
Version:
Collection of libraries for building collaborative editing apps.
93 lines • 3.26 kB
JavaScript
import { LeafBlock, Peritext } from '../peritext';
import { ExtensionId } from '../constants';
import { MNEMONIC } from './constants';
import { ExtNode } from '../../json-crdt/extensions/ExtNode';
import { Slice } from '../peritext/slice/Slice';
const blockToSlateNode = (block) => {
if (block instanceof LeafBlock) {
const textChildren = [];
for (let iterator = block.texts0(), inline; (inline = iterator());) {
const text = inline.text();
const attr = inline.attr();
const attrKeys = Object.keys(attr);
// Skip only if there's no text AND no decorations
if (!text && attrKeys.length === 0)
continue;
const textNode = { text: text || '' };
const length = attrKeys.length;
ATTRS: for (let i = 0; i < length; i++) {
const tag = attrKeys[i];
const stack = attr[tag];
if (!stack || stack.length <= 0)
continue ATTRS;
const slice = stack[0].slice;
if (!(slice instanceof Slice))
continue ATTRS;
const data = slice.data();
if (data && typeof data === 'object' && !Array.isArray(data))
Object.assign(textNode, { [tag]: data });
else
textNode[tag] = data !== undefined ? data : true;
}
textChildren.push(textNode);
}
const node = {
type: block.tag() + '',
children: textChildren.length ? textChildren : [{ text: '' }],
};
const attr = block.attr();
if (typeof attr === 'object')
Object.assign(node, attr);
return node;
}
else {
const children = [];
const blockChildren = block.children;
const length = blockChildren.length;
for (let i = 0; i < length; i++)
children.push(blockToSlateNode(blockChildren[i]));
const attr = block.attr();
const node = {
...(attr && typeof attr === 'object' ? attr : {}),
type: block.tag() + '',
children: children.length ? children : [{ text: '' }],
};
return node;
}
};
export class SlateNode 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.slate;
name() {
return MNEMONIC;
}
_view = null;
_viewHash = -1;
view() {
const { txt } = this;
const hash = txt.refresh();
if (this._view && hash === this._viewHash)
return this._view;
const block = txt.blocks.root;
const node = blockToSlateNode(block);
const content = (node?.children ?? []);
// console.log(JSON.stringify(content, null, 2));
this._viewHash = hash;
this._view = content;
return content;
}
}
//# sourceMappingURL=SlateNode.js.map