All files / collaborative-slate/src/sync toSlate.ts

96% Statements 48/50
84.84% Branches 28/33
100% Functions 2/2
100% Lines 39/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 566x 6x     6x 2194x 1349x 1349x 1809x 1809x 1809x 1809x 1633x 1633x 1633x 489x 489x 489x 489x 489x 489x 489x 473x   1633x   1349x       1349x 1349x 1349x   845x 845x 845x 1484x 845x 845x         845x       6x 710x 710x 710x 710x 710x    
import {Slice} from 'json-joy/lib/json-crdt-extensions/peritext/slice/Slice';
import {type Block, type Inline, LeafBlock, type Peritext} from 'json-joy/lib/json-crdt-extensions/peritext';
import type {SlateDocument, SlateElementNode, SlateTextNode} from '../types';
 
const blockToSlateNode = (block: Block | LeafBlock): SlateElementNode => {
  if (block instanceof LeafBlock) {
    const textChildren: SlateTextNode[] = [];
    for (let iterator = block.texts0(), inline: Inline | undefined; (inline = iterator()); ) {
      const text = inline.text();
      const attr = inline.attr();
      const attrKeys = Object.keys(attr);
      if (!text && attrKeys.length === 0) continue;
      const textNode: SlateTextNode = {text: text || ''};
      const length = attrKeys.length;
      ATTRS: for (let i = 0; i < length; i++) {
        const tag = attrKeys[i];
        const stack = attr[tag];
        Iif (!stack || stack.length <= 0) continue ATTRS;
        const slice = stack[0].slice;
        Iif (!(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: SlateElementNode = {
      type: block.tag() + '',
      children: textChildren.length ? textChildren : [{text: ''}],
    };
    const attr = block.attr();
    Eif (typeof attr === 'object') Object.assign(node, attr);
    return node;
  } else {
    const children: SlateElementNode[] = [];
    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: SlateElementNode = {
      ...(attr && typeof attr === 'object' ? attr : {}),
      type: block.tag() + '',
      children: children.length ? children : [{text: ''}],
    };
    return node;
  }
};
 
export const toSlate = (txt: Peritext): SlateDocument => {
  txt.refresh();
  const block = txt.blocks.root;
  const node = blockToSlateNode(block);
  const content: SlateDocument = (node?.children ?? []) as SlateDocument;
  return content;
};