Skip to content

Commit 8b1b8cf

Browse files
committed
feat(json-crdt-peritext-ui): 🎸 update fomartting implementation
1 parent 8a8ac43 commit 8b1b8cf

File tree

1 file changed

+29
-20
lines changed

1 file changed

+29
-20
lines changed

src/json-crdt-extensions/peritext/editor/EditorSlices.ts

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,48 @@ import type {Slices} from '../slice/Slices';
66
import type {ITimestampStruct} from '../../../json-crdt-patch';
77
import type {Range} from '../rga/Range';
88

9+
const forEachRange = <T, S extends PersistedSlice<T>>(selection: Range<T>[] | IterableIterator<Range<T>>, callback: (range: Range<T>) => S): S[] => {
10+
const slices: S[] = [];
11+
for (const cursor of selection) {
12+
const slice = callback(cursor);
13+
slices.push(slice);
14+
}
15+
return slices;
16+
};
17+
918
export class EditorSlices<T = string> {
1019
constructor(
1120
protected readonly txt: Peritext<T>,
1221
public readonly slices: Slices<T>,
1322
) {}
1423

15-
protected insAtCursors<S extends PersistedSlice<T>>(selection: Range<T>[] | IterableIterator<Range<T>>, callback: (range: Range<T>) => S): S[] {
16-
const slices: S[] = [];
17-
for (const cursor of selection) {
18-
const slice = callback(cursor);
19-
slices.push(slice);
20-
}
21-
return slices;
22-
}
23-
24-
public insStack(type: SliceType, data?: unknown | ITimestampStruct, selection: Range<T>[] | IterableIterator<Range<T>> = this.txt.editor.cursors()): PersistedSlice<T>[] {
25-
return this.insAtCursors(selection, (cursor) => this.slices.insStack(cursor.range(), type, data));
24+
public insStack(type: SliceType, data?: unknown | ITimestampStruct, selection?: Range<T>[] | IterableIterator<Range<T>>): PersistedSlice<T>[] {
25+
const {slices, txt} = this;
26+
selection ||= txt.editor.cursors();
27+
return forEachRange(selection, (range) => slices.insStack(range.range(), type, data));
2628
}
2729

28-
public insOne(type: SliceType, data?: unknown | ITimestampStruct, selection: Range<T>[] | IterableIterator<Range<T>> = this.txt.editor.cursors()): PersistedSlice<T>[] {
29-
return this.insAtCursors(selection, (cursor) => this.slices.insOne(cursor.range(), type, data));
30+
public insOne(type: SliceType, data?: unknown | ITimestampStruct, selection?: Range<T>[] | IterableIterator<Range<T>>): PersistedSlice<T>[] {
31+
const {slices, txt} = this;
32+
selection ||= txt.editor.cursors();
33+
return forEachRange(selection, (range) => slices.insOne(range.range(), type, data));
3034
}
3135

32-
public insErase(type: SliceType, data?: unknown | ITimestampStruct, selection: Range<T>[] | IterableIterator<Range<T>> = this.txt.editor.cursors()): PersistedSlice<T>[] {
33-
return this.insAtCursors(selection, (cursor) => this.slices.insErase(cursor.range(), type, data));
36+
public insErase(type: SliceType, data?: unknown | ITimestampStruct, selection?: Range<T>[] | IterableIterator<Range<T>>): PersistedSlice<T>[] {
37+
const {slices, txt} = this;
38+
selection ||= txt.editor.cursors();
39+
return forEachRange(selection, (range) => slices.insErase(range.range(), type, data));
3440
}
3541

36-
public insMarker(type: SliceType, data?: unknown, separator?: string, selection: Range<T>[] | IterableIterator<Range<T>> = this.txt.editor.cursors()): MarkerSlice<T>[] {
37-
return this.insAtCursors(selection, (cursor) => {
38-
this.txt.editor.collapseCursor(cursor);
39-
const after = cursor.start.clone();
42+
public insMarker(type: SliceType, data?: unknown, separator?: string, selection?: Range<T>[] | IterableIterator<Range<T>>): MarkerSlice<T>[] {
43+
const {slices, txt} = this;
44+
const editor = txt.editor;
45+
selection ||= txt.editor.cursors();
46+
return forEachRange(selection, (range) => {
47+
editor.collapseCursor(range);
48+
const after = range.start.clone();
4049
after.refAfter();
41-
const marker = this.slices.insMarkerAfter(after.id, type, data, separator);
50+
const marker = slices.insMarkerAfter(after.id, type, data, separator);
4251
return marker;
4352
});
4453
}

0 commit comments

Comments
 (0)