Skip to content

Commit

Permalink
feat(json-crdt-extensions): 🎸 can return block marker when iterating
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jun 7, 2024
1 parent e73f59b commit 0e66aa6
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
10 changes: 7 additions & 3 deletions src/json-crdt-extensions/peritext/block/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,16 @@ export class Block<Attr = unknown> implements IBlock, Printable, Stateful {
* Iterate through all overlay points of this block, until the next marker
* (regardless if that marker is a child or not).
*/
public points0(): UndefIterator<OverlayPoint<T>> {
public points0(withMarker: boolean = false): UndefIterator<OverlayPoint<T>> {
const txt = this.txt;
const overlay = txt.overlay;
const iterator = overlay.points0(this.marker);
let closed = false;
return () => {
if (withMarker) {
withMarker = false;
return this.marker ?? overlay.START;
}
if (closed) return;
const point = iterator();
if (!point) return;
Expand All @@ -67,8 +71,8 @@ export class Block<Attr = unknown> implements IBlock, Printable, Stateful {
};
}

public points(): IterableIterator<OverlayPoint<T>> {
return new UndefEndIter(this.points0());
public points(withMarker?: boolean): IterableIterator<OverlayPoint<T>> {
return new UndefEndIter(this.points0(withMarker));
}

// ----------------------------------------------------------------- Stateful
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {setupHelloWorldKit} from '../../__tests__/setup';
import {MarkerOverlayPoint} from '../../overlay/MarkerOverlayPoint';
import {OverlayPoint} from '../../overlay/OverlayPoint';

describe('points', () => {
Expand All @@ -11,6 +12,16 @@ describe('points', () => {
expect(iterator()).toBe(undefined);
});

test('using flag, can receive START marker in empty document', () => {
const {peritext} = setupHelloWorldKit();
peritext.refresh();
const blocks = peritext.blocks;
const block = blocks.root.children[0]!;
const iterator = block.points0(true);
expect(iterator()).toBeInstanceOf(OverlayPoint);
expect(iterator()).toBe(undefined);
});

test('returns all overlay points in single block document', () => {
const {peritext} = setupHelloWorldKit();
peritext.editor.cursor.setAt(3, 3);
Expand All @@ -26,8 +37,22 @@ describe('points', () => {
expect(point3).toBe(undefined);
});

test('returns only points within that block, in two-block document', () => {
test('returns all overlay points in single block document, including start marker', () => {
const {peritext} = setupHelloWorldKit();
peritext.editor.cursor.setAt(3, 3);
peritext.editor.saved.insStack('bold');
peritext.refresh();
const block = peritext.blocks.root.children[0]!;
const iterator = block.points0(true);
expect(iterator()).toBeInstanceOf(OverlayPoint);
expect(iterator()).toBeInstanceOf(OverlayPoint);
expect(iterator()).toBeInstanceOf(OverlayPoint);
expect(iterator()).toBe(undefined);
});

const setupTwoBlockDocument = () => {
const kit = setupHelloWorldKit();
const {peritext} = kit;
peritext.editor.cursor.setAt(1, 2);
peritext.editor.saved.insStack('bold');
peritext.editor.cursor.setAt(7, 2);
Expand All @@ -38,6 +63,11 @@ describe('points', () => {
peritext.editor.saved.insMarker('p');
peritext.editor.delCursors();
peritext.refresh();
return kit;
};

test('returns only points within that block, in two-block document', () => {
const {peritext} = setupTwoBlockDocument();
expect(peritext.blocks.root.children.length).toBe(2);
const block1 = peritext.blocks.root.children[0]!;
const block2 = peritext.blocks.root.children[1]!;
Expand All @@ -46,4 +76,18 @@ describe('points', () => {
expect(points1.length).toBe(2);
expect(points2.length).toBe(4);
});

test('can iterate including marker points, in two-block document', () => {
const {peritext} = setupTwoBlockDocument();
expect(peritext.blocks.root.children.length).toBe(2);
const block1 = peritext.blocks.root.children[0]!;
const block2 = peritext.blocks.root.children[1]!;
const points1 = [...block1.points(true)];
const points2 = [...block2.points(true)];
expect(points1.length).toBe(3);
expect(points2.length).toBe(5);
expect(points1[0]).toBeInstanceOf(OverlayPoint);
expect(points1[0]).toBe(peritext.overlay.START);
expect(points2[0]).toBeInstanceOf(MarkerOverlayPoint);
});
});

0 comments on commit 0e66aa6

Please sign in to comment.