Skip to content

Commit 4e7bc70

Browse files
authored
Merge pull request #918 from streamich/jsx
JSX for rich-text document building
2 parents 35c9c40 + 861c746 commit 4e7bc70

File tree

9 files changed

+94
-24
lines changed

9 files changed

+94
-24
lines changed

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,16 @@
140140
"jest": {
141141
"moduleFileExtensions": [
142142
"ts",
143-
"js"
143+
"js",
144+
"tsx"
144145
],
145146
"transform": {
146-
"^.+\\.ts$": "ts-jest"
147+
"^.+\\.tsx?$": "ts-jest"
147148
},
148149
"transformIgnorePatterns": [
149150
".*/node_modules/.*"
150151
],
151-
"testRegex": ".*/(__tests__|__jest__|demo)/.*\\.(test|spec)\\.ts$"
152+
"testRegex": ".*/(__tests__|__jest__|demo)/.*\\.(test|spec)\\.tsx?$"
152153
},
153154
"config": {
154155
"commitizen": {

src/json-crdt-extensions/peritext/block/types.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import type {SliceStacking} from '../slice/constants';
22

3-
export type PeritextMlNode = string | PeritextMlElement;
4-
3+
export type PeritextMlNode = PeritextMlText | PeritextMlElement;
4+
export type PeritextMlText = string;
55
export type PeritextMlElement<Tag extends string | number = string | number, Data = unknown, Inline = boolean> = [
66
tag: Tag,
77
attrs: null | PeritextMlAttributes<Data, Inline>,
88
...children: PeritextMlNode[],
99
];
1010

11+
/**
12+
* @todo Make this an array tuple.
13+
*/
1114
export interface PeritextMlAttributes<Data = unknown, Inline = boolean> {
1215
data?: Data;
1316
inline?: Inline;

src/json-crdt-extensions/peritext/slice/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const enum SliceTypeCon {
4545
collapse = 28, // Collapsible block
4646
note = 29, // Note block
4747
mathblock = 30, // <math> block
48+
div = 31,
4849

4950
// ------------------------------------------------ inline slices (-64 to -1)
5051
Cursor = -1,
@@ -113,6 +114,7 @@ export enum SliceTypeName {
113114
collapse = SliceTypeCon.collapse,
114115
note = SliceTypeCon.note,
115116
mathblock = SliceTypeCon.mathblock,
117+
div = SliceTypeCon.div,
116118

117119
Cursor = SliceTypeCon.Cursor,
118120
RemoteCursor = SliceTypeCon.RemoteCursor,

src/json-crdt-extensions/peritext/transfer/PeritextDataTransfer.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ export class PeritextDataTransfer<T = string> {
7777
return tools.toHast(json);
7878
}
7979

80-
public toHtml(range: Range<T>, tab?: string, indent?: string): string {
80+
public toHtml(range?: Range<T>, tab?: string, indent?: string): string {
81+
if (!range) range = this.txt.rangeAll();
82+
if (!range) return '';
8183
const tools = this.htmlE();
8284
const json = this.toJson(range);
8385
return tools.toHtml(json, tab, indent);

src/json-crdt-extensions/peritext/transfer/__tests__/PeritextDataTransfer.spec.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,5 @@
1-
import * as htmlExport from '../export-html';
2-
import * as htmlImport from '../import-html';
3-
import * as mdExport from '../export-markdown';
4-
import * as mdImport from '../import-markdown';
5-
import {PeritextDataTransfer} from '../PeritextDataTransfer';
6-
import {setupKit} from '../../__tests__/setup';
71
import {CommonSliceType} from '../../slice';
8-
9-
const setup = () => {
10-
const kit = setupKit();
11-
const transfer = new PeritextDataTransfer(kit.peritext, {
12-
htmlExport,
13-
htmlImport,
14-
mdExport,
15-
mdImport,
16-
});
17-
return {...kit, transfer};
18-
};
2+
import {setup} from './setup';
193

204
const assertMarkdownReExport = (markdown: string) => {
215
const kit = setup();
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/** @jsx h */
2+
/** @jsxFrag h */
3+
import {h} from '../jsx';
4+
import {SliceTypeCon} from '../../slice/constants';
5+
import {setup} from './setup';
6+
7+
test('can create basic JSX elements', () => {
8+
const jsx = (
9+
<div className="test">
10+
<b>Hello</b>
11+
</div>
12+
);
13+
14+
expect(jsx).toEqual([
15+
SliceTypeCon.div,
16+
{data: {className: 'test'}, inline: false, stacking: 0},
17+
[SliceTypeCon.b, {inline: true, stacking: 2}, 'Hello'],
18+
]);
19+
});
20+
21+
test('can import JSX nodes', () => {
22+
const kit = setup();
23+
const jsx = (
24+
<>
25+
<p>
26+
<b>Hello</b> <u>world</u>!
27+
</p>
28+
<blockquote>
29+
<p>Test</p>
30+
</blockquote>
31+
</>
32+
);
33+
kit.transfer.fromJson(0, jsx as any);
34+
kit.peritext.refresh();
35+
expect(kit.transfer.toHtml()).toBe('<p><b>Hello</b> <u>world</u>!</p><blockquote><p>Test</p></blockquote>');
36+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as htmlExport from '../export-html';
2+
import * as htmlImport from '../import-html';
3+
import * as mdExport from '../export-markdown';
4+
import * as mdImport from '../import-markdown';
5+
import {PeritextDataTransfer} from '../PeritextDataTransfer';
6+
import {setupKit} from '../../__tests__/setup';
7+
8+
export const setup = () => {
9+
const kit = setupKit();
10+
const transfer = new PeritextDataTransfer(kit.peritext, {
11+
htmlExport,
12+
htmlImport,
13+
mdExport,
14+
mdImport,
15+
});
16+
return {...kit, transfer};
17+
};

src/json-crdt-extensions/peritext/transfer/import-html.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ViewRangeBuilder {
3131
private slices: ViewSlice[] = [];
3232

3333
private build0(node: PeritextMlNode, path: (string | number)[]): boolean {
34-
const skipWhitespace = path.length < 2;
34+
const skipWhitespace = path.length < 1;
3535
if (typeof node === 'string') {
3636
if (skipWhitespace && !node.trim()) return false;
3737
this.text += node;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type {PeritextMlElement, PeritextMlNode} from '../block/types';
2+
import {CommonSliceType} from '../slice';
3+
import {SliceStacking} from '../slice/constants';
4+
5+
export const h = (
6+
tag: string,
7+
props: Record<string, unknown> | null,
8+
...children: PeritextMlNode[]
9+
): PeritextMlElement => {
10+
const attrs: PeritextMlElement[1] = {};
11+
if (props) attrs.data = props;
12+
if ((tag as any) === h) return ['', null, ...children];
13+
const num = CommonSliceType[tag as any];
14+
if (typeof num === 'number') {
15+
const inline = num < 0;
16+
attrs.inline = inline;
17+
attrs.stacking = inline ? (props ? SliceStacking.Many : SliceStacking.One) : SliceStacking.Marker;
18+
return [num, attrs, ...children];
19+
} else {
20+
const inline = !props;
21+
attrs.inline = inline;
22+
attrs.stacking = inline ? (props ? SliceStacking.Many : SliceStacking.One) : SliceStacking.Marker;
23+
return [tag, attrs, ...children];
24+
}
25+
};

0 commit comments

Comments
 (0)