1
- import { SliceBehavior , type SliceTypeCon } from '../slice/constants' ;
1
+ import { s } from '../../../json-crdt-patch' ;
2
+ import { SliceBehavior , SliceTypeCon as TAG } from '../slice/constants' ;
2
3
import { CommonSliceType } from '../slice' ;
3
4
import { SliceRegistryEntry } from './SliceRegistryEntry' ;
4
5
import { printTree } from 'tree-dump/lib/printTree' ;
5
6
import type { PeritextMlElement } from '../block/types' ;
6
7
import type { JsonMlElement } from 'very-small-parser/lib/html/json-ml/types' ;
7
8
import type { FromHtmlConverter , ToHtmlConverter } from './types' ;
8
9
import type { Printable } from 'tree-dump' ;
10
+ import type { JsonNodeView } from '../../../json-crdt/nodes' ;
11
+ import type { SchemaToJsonNode } from '../../../json-crdt/schema/types' ;
9
12
10
- export type TypeTag = SliceTypeCon | number | string ;
13
+ const undefSchema = s . con ( undefined ) ;
14
+
15
+ export type TypeTag = TAG | number | string ;
11
16
12
17
/**
13
18
* Slice registry contains a record of possible inline an block formatting
@@ -18,6 +23,114 @@ export type TypeTag = SliceTypeCon | number | string;
18
23
* `/slices` directory.
19
24
*/
20
25
export class SliceRegistry implements Printable {
26
+ /**
27
+ * Creates a new slice registry with common tag registered.
28
+ */
29
+ public static readonly withCommon = ( ) : SliceRegistry => {
30
+ const registry = new SliceRegistry ( ) ;
31
+ // --------------------------------------- Inline elements with "One" behavior
32
+ const i0 = < Tag extends TypeTag = TypeTag > (
33
+ tag : Tag ,
34
+ fromHtml ?: SliceRegistryEntry < SliceBehavior . One , Tag , typeof undefSchema > [ 'fromHtml' ] ,
35
+ ) : void => {
36
+ registry . add ( new SliceRegistryEntry ( SliceBehavior . One , tag , undefSchema , false , void 0 , fromHtml ) ) ;
37
+ } ;
38
+ const i1 = < Tag extends TypeTag = TypeTag > ( tag : Tag , htmlTags : string [ ] ) : void => {
39
+ const fromHtml = { } as Record < any , any > ;
40
+ for ( const htmlTag of htmlTags ) fromHtml [ htmlTag ] = ( ) => [ tag , null ] ;
41
+ i0 ( tag , fromHtml ) ;
42
+ } ;
43
+ i1 ( TAG . i , [ 'i' , 'em' ] ) ;
44
+ i1 ( TAG . b , [ 'b' , 'strong' ] ) ;
45
+ i1 ( TAG . s , [ 's' , 'strike' ] ) ;
46
+ i0 ( TAG . u ) ;
47
+ i0 ( TAG . code ) ;
48
+ i0 ( TAG . mark ) ;
49
+ i0 ( TAG . kbd ) ;
50
+ i0 ( TAG . del ) ;
51
+ i0 ( TAG . ins ) ;
52
+ i0 ( TAG . sup ) ;
53
+ i0 ( TAG . sub ) ;
54
+ i0 ( TAG . math ) ;
55
+
56
+ // -------------------------------------- Inline elements with "Many" behavior
57
+ const aSchema = s . obj ( { } , {
58
+ href : s . str < string > ( '' ) ,
59
+ title : s . str < string > ( '' ) ,
60
+ } ) ;
61
+ registry . add (
62
+ new SliceRegistryEntry ( SliceBehavior . Many , TAG . a , aSchema , false , void 0 , {
63
+ a : ( jsonml ) => {
64
+ const attr = jsonml [ 1 ] || { } ;
65
+ const data : JsonNodeView < SchemaToJsonNode < typeof aSchema > > = {
66
+ href : attr . href ?? '' ,
67
+ title : attr . title ?? '' ,
68
+ } ;
69
+ return [ TAG . a , { data, inline : true } ] as PeritextMlElement < TAG . a , any , true > ;
70
+ } ,
71
+ } ) ,
72
+ ) ;
73
+
74
+ // TODO: add more default annotations with "Many" behavior
75
+ // comment = SliceTypeCon.comment,
76
+ // font = SliceTypeCon.font,
77
+ // col = SliceTypeCon.col,
78
+ // bg = SliceTypeCon.bg,
79
+ // hidden = SliceTypeCon.hidden,
80
+ // footnote = SliceTypeCon.footnote,
81
+ // ref = SliceTypeCon.ref,
82
+ // iaside = SliceTypeCon.iaside,
83
+ // iembed = SliceTypeCon.iembed,
84
+ // bookmark = SliceTypeCon.bookmark,
85
+
86
+ // ------------------------------------- Block elements with "Marker" behavior
87
+ const commonBlockSchema = s . obj (
88
+ { } ,
89
+ {
90
+ indent : s . con ( 0 ) ,
91
+ align : s . str < 'left' | 'center' | 'right' | 'justify' > ( 'left' ) ,
92
+ } ,
93
+ ) ;
94
+ const b0 = < Tag extends TypeTag = TypeTag > ( tag : Tag , container : boolean ) => {
95
+ registry . add ( new SliceRegistryEntry ( SliceBehavior . Marker , tag , commonBlockSchema , container ) ) ;
96
+ } ;
97
+ b0 ( TAG . p , false ) ;
98
+ b0 ( TAG . blockquote , true ) ;
99
+ b0 ( TAG . codeblock , false ) ;
100
+ b0 ( TAG . pre , false ) ;
101
+ b0 ( TAG . ul , true ) ;
102
+ b0 ( TAG . ol , true ) ;
103
+ b0 ( TAG . tl , true ) ;
104
+ b0 ( TAG . ol , true ) ;
105
+ b0 ( TAG . li , true ) ;
106
+ b0 ( TAG . h1 , false ) ;
107
+ b0 ( TAG . h2 , false ) ;
108
+ b0 ( TAG . h3 , false ) ;
109
+ b0 ( TAG . h4 , false ) ;
110
+ b0 ( TAG . h5 , false ) ;
111
+ b0 ( TAG . h6 , false ) ;
112
+ b0 ( TAG . title , false ) ;
113
+ b0 ( TAG . subtitle , false ) ;
114
+ // b0(TAG.br, false);
115
+ // b0(TAG.nl, false);
116
+ // b0(TAG.hr, false);
117
+ // b0(TAG.page, false);
118
+ // b0(TAG.aside, true);
119
+ // b0(TAG.embed, false);
120
+ // b0(TAG.column, true);
121
+ // b0(TAG.contents, true);
122
+ // b0(TAG.table, true);
123
+ // b0(TAG.row, true);
124
+ // b0(TAG.cell, true);
125
+ // b0(TAG.collapselist, true);
126
+ // b0(TAG.collapse, true);
127
+ // b0(TAG.note, true);
128
+ // b0(TAG.mathblock, false);
129
+
130
+ return registry ;
131
+ } ;
132
+
133
+
21
134
private map : Map < TypeTag , SliceRegistryEntry > = new Map ( ) ;
22
135
private _fromHtml : Map < string , [ entry : SliceRegistryEntry , converter : FromHtmlConverter ] [ ] > = new Map ( ) ;
23
136
@@ -38,7 +151,7 @@ export class SliceRegistry implements Printable {
38
151
_fromHtml . set ( htmlTag , converters ) ;
39
152
}
40
153
}
41
- const tagStr = CommonSliceType [ tag as SliceTypeCon ] ;
154
+ const tagStr = CommonSliceType [ tag as TAG ] ;
42
155
if ( tagStr && typeof tagStr === 'string' ) _fromHtml . set ( tagStr , [ [ entry , ( ) => [ tag , null ] ] ] ) ;
43
156
}
44
157
0 commit comments