Skip to content

Commit

Permalink
feat(json-crdt-extensions): 🎸 improve JSOM-ML generation for block nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Nov 26, 2024
1 parent 43ad61d commit fb45ba7
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 13 deletions.
30 changes: 29 additions & 1 deletion src/json-crdt-extensions/peritext/block/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import {UndefEndIter, type UndefIterator} from '../../../util/iterator';
import {Inline} from './Inline';
import {formatType} from '../slice/util';
import {Range} from '../rga/Range';
import {SliceTypeName} from '../slice/constants';
import type {Point} from '../rga/Point';
import type {OverlayPoint} from '../overlay/OverlayPoint';
import type {Path} from '@jsonjoy.com/json-pointer';
import type {Printable} from 'tree-dump';
import type {Peritext} from '../Peritext';
import type {Stateful} from '../types';
import type {OverlayTuple} from '../overlay/types';
import type {JsonMlNode} from '../../../json-ml';
import type {JsonMlElement, JsonMlNode} from '../../../json-ml';

export interface IBlock {
readonly path: Path;
Expand Down Expand Up @@ -52,6 +53,33 @@ export class Block<Attr = unknown> extends Range implements IBlock, Printable, S
return length ? path[length - 1] : '';
}

public htmlTag(): string {
const tag = this.tag();
switch (typeof tag) {
case 'string': return tag.toLowerCase();
case 'number': return SliceTypeName[tag] || 'div';
default: return 'div';
}
}

public jsonMlNode(): JsonMlElement {
const props: Record<string, string> = {};
const node: JsonMlElement = ['div', props];
const tag = this.tag();
switch (typeof tag) {
case 'string':
node[0] = tag;
break;
case 'number':
const tag0 = SliceTypeName[tag];
if (tag0) node[0] = tag0; else props['data-tag'] = tag + '';
break;
}
const attr = this.attr();
if (attr !== undefined) props['data-attr'] = JSON.stringify(attr);
return node;
}

public attr(): Attr | undefined {
return this.marker?.data() as Attr | undefined;
}
Expand Down
6 changes: 6 additions & 0 deletions src/json-crdt-extensions/peritext/block/Fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {Printable} from 'tree-dump/lib/types';
import type {Peritext} from '../Peritext';
import type {Point} from '../rga/Point';
import type {JsonMlNode} from '../../../json-ml/types';
import {toHtml} from '../../../json-ml';

/**
* A *fragment* represents a structural slice of a rich-text document. A
Expand All @@ -36,6 +37,11 @@ export class Fragment extends Range implements Printable, Stateful {
return this.root.toJsonMl();
}

toHtml(): string {
const json = this.root.toJsonMl();
return toHtml(json);
}

// ---------------------------------------------------------------- Printable

public toString(tab: string = ''): string {
Expand Down
2 changes: 1 addition & 1 deletion src/json-crdt-extensions/peritext/block/LeafBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class LeafBlock<Attr = unknown> extends Block<Attr> {
// ------------------------------------------------------------------- export

toJsonMl(): JsonMlNode {
let node: JsonMlNode = ['div', {}];
const node = this.jsonMlNode();
for (const inline of this.texts()) {
const span = inline.toJsonMl();
if (span) node.push(span);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import {
type Kit,
setupAlphabetKit,
} from '../../__tests__/setup';
import {CommonSliceType} from '../../slice';

const runTests = (setup: () => Kit) => {
test('...', () => {
const {editor, peritext} = setup();
editor.cursor.setAt(10);
editor.saved.insMarker(['p'], 'p1');
editor.saved.insMarker(CommonSliceType.p);
peritext.refresh();
const fragment = peritext.fragment(peritext.rangeAt(4, 10));
fragment.refresh();
Expand Down
22 changes: 13 additions & 9 deletions src/json-crdt-extensions/peritext/slice/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ export enum CursorAnchor {
End = 1,
}

export enum SliceTypeCon {
export const enum SliceTypeCon {
// ---------------------------------------------------- block slices (0 to 64)
p = 0, // <p>
blockquote = 1, // <blockquote>
codeblock = 2, // <pre><code>
pre = 3, // <pre>
ul = 4, // <ul>
ol = 5, // <ol>
TaskList = 6, // - [ ] Task list
tasklist = 6, // - [ ] Task list
h1 = 7, // <h1>
h2 = 8, // <h2>
h3 = 9, // <h3>
Expand All @@ -37,9 +37,9 @@ export enum SliceTypeCon {
table = 23, // <table>
row = 24, // Table row
cell = 25, // Table cell
CollapseList = 26, // Collapsible list - > List item
Collapse = 27, // Collapsible block
Note = 28, // Note block
collapselist = 26, // Collapsible list - > List item
collapse = 27, // Collapsible block
note = 28, // Note block

// ------------------------------------------------ inline slices (-64 to -1)
Cursor = -1,
Expand Down Expand Up @@ -69,14 +69,18 @@ export enum SliceTypeCon {
bookmark = -25, // UI for creating a link to this slice
}

/**
* All type name must be fully lowercase, as HTML custom element tag names must
* be lowercase.
*/
export enum SliceTypeName {
p = SliceTypeCon.p,
blockquote = SliceTypeCon.blockquote,
codeblock = SliceTypeCon.codeblock,
pre = SliceTypeCon.pre,
ul = SliceTypeCon.ul,
ol = SliceTypeCon.ol,
TaskList = SliceTypeCon.TaskList,
tasklist = SliceTypeCon.tasklist,
h1 = SliceTypeCon.h1,
h2 = SliceTypeCon.h2,
h3 = SliceTypeCon.h3,
Expand All @@ -96,9 +100,9 @@ export enum SliceTypeName {
table = SliceTypeCon.table,
row = SliceTypeCon.row,
cell = SliceTypeCon.cell,
CollapseList = SliceTypeCon.CollapseList,
Collapse = SliceTypeCon.Collapse,
Note = SliceTypeCon.Note,
collapselist = SliceTypeCon.collapselist,
collapse = SliceTypeCon.collapse,
note = SliceTypeCon.note,

Cursor = SliceTypeCon.Cursor,
RemoteCursor = SliceTypeCon.RemoteCursor,
Expand Down
3 changes: 2 additions & 1 deletion src/json-ml/types.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export type JsonMlNode = string | [tag: string, attrs: null | Record<string, string>, ...children: JsonMlNode[]];
export type JsonMlNode = string | JsonMlElement;
export type JsonMlElement = [tag: string, attrs: null | Record<string, string>, ...children: JsonMlNode[]];

0 comments on commit fb45ba7

Please sign in to comment.