Skip to content

Commit 32b481d

Browse files
committed
feat(json-crdt-extensions): 🎸 improve marker point treatment in overlay
1 parent a756ff7 commit 32b481d

File tree

5 files changed

+35
-24
lines changed

5 files changed

+35
-24
lines changed

src/json-crdt-extensions/peritext/__tests__/Peritext.overlay.spec.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ const setup = () => {
1919
test('can insert markers', () => {
2020
const {peritext} = setup();
2121
const {editor} = peritext;
22-
expect(size(peritext.overlay.root)).toBe(0);
22+
expect(peritext.overlay.all().length).toBe(0);
2323
editor.cursor.setAt(0);
24+
peritext.refresh();
25+
expect(peritext.overlay.all().length).toBe(1);
2426
editor.insMarker(['p'], '<p>');
2527
peritext.refresh();
26-
expect(size(peritext.overlay.root)).toBe(1);
28+
expect(size(peritext.overlay.root)).toBe(2);
2729
editor.cursor.setAt(9);
2830
editor.insMarker(['p'], '<p>');
2931
peritext.refresh();

src/json-crdt-extensions/peritext/overlay/MarkerOverlayPoint.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ export class MarkerOverlayPoint<T = string> extends OverlayPoint<T> {
4646
}
4747

4848
public toString(tab: string = '', lite?: boolean): string {
49-
return super.toString(tab, lite) + (lite ? '' : printTree(tab, [(tab) => this.marker.toString(tab)]));
49+
return this.toStringName(tab, lite) + (lite ? '' : printTree(tab, [
50+
(tab) => this.marker.toString(tab),
51+
...this.layers.map((slice) => (tab: string) => slice.toString(tab)),
52+
...this.markers.map((slice) => (tab: string) => slice.toString(tab)),
53+
]));
5054
}
5155
}

src/json-crdt-extensions/peritext/overlay/Overlay.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export class Overlay<T = string> implements Printable, Stateful {
124124
if (predicate(point)) return point;
125125
point = next(point);
126126
}
127-
return undefined;
127+
return;
128128
}
129129

130130
public chunkSlices0(
@@ -372,25 +372,30 @@ export class Overlay<T = string> implements Printable, Stateful {
372372
}
373373

374374
private insSlice(slice: Slice<T>): [start: OverlayPoint<T>, end: OverlayPoint<T>] {
375-
console.log('ins slice', slice+'')
375+
// TODO: Test cases where the inserted slice is collapsed to one point.
376376
const x0 = slice.start;
377377
const x1 = slice.end;
378378
const [start, isStartNew] = this.upsertPoint(x0);
379379
const [end, isEndNew] = this.upsertPoint(x1);
380+
const isCollapsed = x0.cmp(x1) === 0;
380381
start.refs.push(new OverlayRefSliceStart(slice));
381382
end.refs.push(new OverlayRefSliceEnd(slice));
382383
if (isStartNew) {
383384
const beforeStartPoint = prev(start);
384385
if (beforeStartPoint) start.layers.push(...beforeStartPoint.layers);
385386
}
386-
if (isEndNew) {
387-
const beforeEndPoint = prev(end);
388-
if (beforeEndPoint) end.layers.push(...beforeEndPoint.layers);
387+
if (!isCollapsed) {
388+
389+
if (isEndNew) {
390+
const beforeEndPoint = prev(end);
391+
if (beforeEndPoint) end.layers.push(...beforeEndPoint.layers);
392+
}
393+
let curr: OverlayPoint<T> | undefined = start;
394+
do curr.addLayer(slice); while ((curr = next(curr)) && (curr !== end));
395+
} else {
396+
// TODO: review if this is needed:
397+
start.addMarker(slice);
389398
}
390-
let curr: OverlayPoint<T> | undefined = start;
391-
do curr.addLayer(slice); while ((curr = next(curr)) && (curr !== end));
392-
const isCollapsed = x0.cmp(x1) === 0;
393-
if (isCollapsed) start.addMarker(slice);
394399
return [start, end];
395400
}
396401

@@ -448,7 +453,7 @@ export class Overlay<T = string> implements Printable, Stateful {
448453
else insertLeft(point, pivot);
449454
}
450455
if (this.root !== point) this.root = splay(this.root!, point, 10);
451-
return undefined;
456+
return;
452457
}
453458

454459
private delPoint(point: OverlayPoint<T>): void {

src/json-crdt-extensions/peritext/overlay/__tests__/Overlay.spec.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -200,22 +200,21 @@ describe('slices', () => {
200200
expect(point2.anchor).toBe(Anchor.After);
201201
});
202202

203-
test.only('intersecting slice before split, should not update the split', () => {
203+
test('intersecting slice before split, should not update the split', () => {
204204
const {peritext} = setup();
205205
peritext.editor.cursor.setAt(6);
206206
peritext.editor.insMarker(['p']);
207207
peritext.refresh();
208-
console.log(peritext + '');
209208
const point = peritext.overlay.find((point) => point instanceof MarkerOverlayPoint)!;
210209
expect(point.layers.length).toBe(0);
211-
// peritext.editor.cursor.setAt(2, 2);
212-
// peritext.editor.insStackSlice('<i>');
213-
// peritext.refresh();
214-
// expect(point.layers.length).toBe(0);
215-
// peritext.editor.cursor.setAt(2, 1);
216-
// peritext.editor.insStackSlice('<b>');
217-
// peritext.refresh();
218-
// expect(point.layers.length).toBe(0);
210+
peritext.editor.cursor.setAt(2, 2);
211+
peritext.editor.insStackSlice('<i>');
212+
peritext.refresh();
213+
expect(point.layers.length).toBe(0);
214+
peritext.editor.cursor.setAt(2, 1);
215+
peritext.editor.insStackSlice('<b>');
216+
peritext.refresh();
217+
expect(point.layers.length).toBe(0);
219218
});
220219
});
221220

src/json-crdt-extensions/peritext/rga/Point.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ export class Point<T = string> implements Pick<Stateful, 'refresh'>, Printable {
138138
*/
139139
public viewPos(): number {
140140
const pos = this.pos();
141-
if (pos < 0) return this.isAbsStart() ? 0 : this.rga.length();
141+
const isAbs = equal(this.rga.id, this.id);
142+
if (isAbs) return this.anchor === Anchor.After ? 0 : this.rga.length();
142143
return this.anchor === Anchor.Before ? pos : pos + 1;
143144
}
144145

0 commit comments

Comments
 (0)