All files / json-crdt-extensions/peritext/registry registry.ts

94.44% Statements 51/54
0% Branches 0/6
83.33% Functions 5/6
94.11% Lines 48/51

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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 12562x 62x 62x         62x 3452x 3452x       3452x       41424x     3452x 10356x 20712x 10356x     3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x       3452x       3452x                                                     3452x               3452x 58684x     3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x 3452x                                 3452x           62x  
import {s} from '../../../json-crdt-patch';
import {SliceBehavior, SliceTypeCon as TAG} from '../slice/constants';
import {SliceRegistry, SliceRegistryEntry, type TagType} from './SliceRegistry';
import type {JsonNodeView} from '../../../json-crdt/nodes';
import type {SchemaToJsonNode} from '../../../json-crdt/schema/types';
import type {PeritextMlElement} from '../block/types';
 
export const createRegistry = () => {
  const registry = new SliceRegistry();
  const undefSchema = s.con(undefined);
 
  // --------------------------------------- Inline elements with "One" behavior
 
  const i0 = <Tag extends TagType = TagType>(
    tag: Tag,
    fromHtml?: SliceRegistryEntry<SliceBehavior.One, Tag, typeof undefSchema>['fromHtml'],
  ): void => {
    registry.add(new SliceRegistryEntry(SliceBehavior.One, tag, undefSchema, false, void 0, fromHtml));
  };
 
  const i1 = <Tag extends TagType = TagType>(tag: Tag, htmlTags: string[]): void => {
    const fromHtml = {} as Record<any, any>;
    for (const htmlTag of htmlTags) fromHtml[htmlTag] = () => [tag, null];
    i0(tag, fromHtml);
  };
 
  i1(TAG.i, ['i', 'em']);
  i1(TAG.b, ['b', 'strong']);
  i1(TAG.s, ['s', 'strike']);
  i0(TAG.u);
  i0(TAG.code);
  i0(TAG.mark);
  i0(TAG.kbd);
  i0(TAG.del);
  i0(TAG.ins);
  i0(TAG.sup);
  i0(TAG.sub);
  i0(TAG.math);
 
  // -------------------------------------- Inline elements with "Many" behavior
 
  const aSchema = s.obj({
    href: s.str<string>(''),
    title: s.str<string>(''),
  });
  registry.add(
    new SliceRegistryEntry(SliceBehavior.Many, TAG.a, aSchema, false, void 0, {
      a: (jsonml) => {
        const attr = jsonml[1] || {};
        const data: JsonNodeView<SchemaToJsonNode<typeof aSchema>> = {
          href: attr.href ?? '',
          title: attr.title ?? '',
        };
        return [TAG.a, {data, inline: true}] as PeritextMlElement<TAG.a, any, true>;
      },
    }),
  );
 
  // TODO: add more default annotations with "Many" behavior
  // comment = SliceTypeCon.comment,
  // font = SliceTypeCon.font,
  // col = SliceTypeCon.col,
  // bg = SliceTypeCon.bg,
  // hidden = SliceTypeCon.hidden,
  // footnote = SliceTypeCon.footnote,
  // ref = SliceTypeCon.ref,
  // iaside = SliceTypeCon.iaside,
  // iembed = SliceTypeCon.iembed,
  // bookmark = SliceTypeCon.bookmark,
 
  // ------------------------------------- Block elements with "Marker" behavior
 
  const commonBlockSchema = s.obj(
    {},
    {
      indent: s.con(0),
      align: s.str<'left' | 'center' | 'right' | 'justify'>('left'),
    },
  );
 
  const b0 = <Tag extends TagType = TagType>(tag: Tag, container: boolean) => {
    registry.add(new SliceRegistryEntry(SliceBehavior.Marker, tag, commonBlockSchema, container));
  };
 
  b0(TAG.p, false);
  b0(TAG.blockquote, true);
  b0(TAG.codeblock, false);
  b0(TAG.pre, false);
  b0(TAG.ul, true);
  b0(TAG.ol, true);
  b0(TAG.tl, true);
  b0(TAG.ol, true);
  b0(TAG.li, true);
  b0(TAG.h1, false);
  b0(TAG.h2, false);
  b0(TAG.h3, false);
  b0(TAG.h4, false);
  b0(TAG.h5, false);
  b0(TAG.h6, false);
  b0(TAG.title, false);
  b0(TAG.subtitle, false);
  // b0(TAG.br, false);
  // b0(TAG.nl, false);
  // b0(TAG.hr, false);
  // b0(TAG.page, false);
  // b0(TAG.aside, true);
  // b0(TAG.embed, false);
  // b0(TAG.column, true);
  // b0(TAG.contents, true);
  // b0(TAG.table, true);
  // b0(TAG.row, true);
  // b0(TAG.cell, true);
  // b0(TAG.collapselist, true);
  // b0(TAG.collapse, true);
  // b0(TAG.note, true);
  // b0(TAG.mathblock, false);
 
  return registry;
};
 
/**
 * Default annotation type registry.
 */
export const registry = createRegistry();