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 2117x 1294x 1294x 1743x 1743x 1743x 1743x 1562x 1562x 1562x 434x 434x 434x 434x 434x 434x 434x 418x   1562x   1294x       1294x 1294x 1294x   823x 823x 823x 1429x 823x 823x         823x       6x 688x 688x 688x 688x 688x    
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;
};