From c61b5c01e0f53aeecd9b83a2cfa0badd62a5276b Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Sun, 22 Dec 2024 10:22:49 +0100 Subject: [PATCH 1/7] =?UTF-8?q?test(json-crdt-extensions):=20=F0=9F=92=8D?= =?UTF-8?q?=20improve=20export=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../editor/__tests__/Editor-export.spec.ts | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts index 7590f9668b..28b504089b 100644 --- a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts +++ b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts @@ -1,5 +1,7 @@ import {type Kit, runAlphabetKitTestSuite} from '../../__tests__/setup'; +import {Anchor} from '../../rga/constants'; import {CommonSliceType} from '../../slice'; +import {SliceBehavior, SliceHeaderShift} from '../../slice/constants'; const testSuite = (setup: () => Kit) => { describe('.export()', () => { @@ -10,6 +12,13 @@ const testSuite = (setup: () => Kit) => { expect(json).toEqual(['abcdefghijklmnopqrstuvwxyz', 0, []]); }); + test('can export part of un-annotated document', () => { + const {editor} = setup(); + editor.cursor.setAt(5, 5); + const json = editor.export(editor.cursor); + expect(json).toEqual(['fghij', 5, []]); + }); + test('range which contains bold text', () => { const {editor, peritext} = setup(); editor.cursor.setAt(3, 3); @@ -39,6 +48,48 @@ const testSuite = (setup: () => Kit) => { const json = editor.export(range); expect(json).toEqual(['abcde', 0, [[expect.any(Number), 3, 13, CommonSliceType.b]]]); }); + + test('can export

marker', () => { + const {editor, peritext} = setup(); + editor.cursor.setAt(10); + editor.saved.insMarker(CommonSliceType.p); + const range = peritext.rangeAt(8, 5); + peritext.refresh(); + const json = editor.export(range); + const header = (SliceBehavior.Marker << SliceHeaderShift.Behavior) + + (Anchor.Before << SliceHeaderShift.X1Anchor) + + (Anchor.Before << SliceHeaderShift.X2Anchor); + expect(json).toEqual(['ij\nkl', 8, [ + [header, 10, 10, CommonSliceType.p] + ]]); + }); + + test('can export

marker,

marker, and italic text', () => { + const {editor, peritext} = setup(); + editor.cursor.setAt(15); + editor.saved.insMarker(CommonSliceType.blockquote); + editor.cursor.setAt(10); + editor.saved.insMarker(CommonSliceType.p); + editor.cursor.setAt(12, 2); + editor.saved.insOverwrite(CommonSliceType.i); + const range = peritext.rangeAt(8, 12); + peritext.refresh(); + const json = editor.export(range); + const pHeader = (SliceBehavior.Marker << SliceHeaderShift.Behavior) + + (Anchor.Before << SliceHeaderShift.X1Anchor) + + (Anchor.Before << SliceHeaderShift.X2Anchor); + const iHeader = (SliceBehavior.One << SliceHeaderShift.Behavior) + + (Anchor.Before << SliceHeaderShift.X1Anchor) + + (Anchor.After << SliceHeaderShift.X2Anchor); + const blockquoteHeader = (SliceBehavior.Marker << SliceHeaderShift.Behavior) + + (Anchor.Before << SliceHeaderShift.X1Anchor) + + (Anchor.Before << SliceHeaderShift.X2Anchor); + expect(json).toEqual(['ij\nklmno\npqr', 8, [ + [pHeader, 10, 10, CommonSliceType.p], + [iHeader, 12, 14, CommonSliceType.i], + [blockquoteHeader, 16, 16, CommonSliceType.blockquote], + ]]); + }); }); describe('.import()', () => { From 3d21330452f31cecd14d02e138c4bb229a0ee79a Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Sun, 22 Dec 2024 11:11:56 +0100 Subject: [PATCH 2/7] =?UTF-8?q?feat(json-crdt-extensions):=20=F0=9F=8E=B8?= =?UTF-8?q?=20implement=20block=20split=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../peritext/editor/Editor.ts | 37 ++++++++++++++++++- .../editor/__tests__/Editor-export.spec.ts | 21 +++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/json-crdt-extensions/peritext/editor/Editor.ts b/src/json-crdt-extensions/peritext/editor/Editor.ts index 46e13551e1..c2d9088fca 100644 --- a/src/json-crdt-extensions/peritext/editor/Editor.ts +++ b/src/json-crdt-extensions/peritext/editor/Editor.ts @@ -715,10 +715,45 @@ export class Editor implements Printable { public import(pos: number, view: ViewRange): void { const [text, offset, slices] = view; const txt = this.txt; - txt.insAt(pos, text); const length = slices.length; + const splits: ViewSlice[] = []; + const annotations: ViewSlice[] = []; + const texts: string[] = []; + let start = 0; for (let i = 0; i < length; i++) { const slice = slices[i]; + const [header, x1] = slice; + const behavior: SliceBehavior = (header & SliceHeaderMask.Behavior) >>> SliceHeaderShift.Behavior; + if (behavior === SliceBehavior.Marker) { + const end = x1 - offset; + texts.push(text.slice(start, end)); + start = end + 1; + splits.push(slice); + } + else annotations.push(slice); + } + const lastText = text.slice(start); + const splitLength = splits.length; + start = pos; + for (let i = 0; i < splitLength; i++) { + const str = texts[i]; + const split = splits[i]; + if (str) { + txt.insAt(start, str); + start += str.length; + } + if (split) { + const [,,, type, data] = split; + const after = txt.pointAt(start); + after.refAfter(); + txt.savedSlices.insMarkerAfter(after.id, type, data); + start += 1; + } + } + if (lastText) txt.insAt(start, lastText); + const annotationsLength = annotations.length; + for (let i = 0; i < annotationsLength; i++) { + const slice = annotations[i]; const [header, x1, x2, type, data] = slice; const anchor1: Anchor = (header & SliceHeaderMask.X1Anchor) >>> SliceHeaderShift.X1Anchor; const anchor2: Anchor = (header & SliceHeaderMask.X2Anchor) >>> SliceHeaderShift.X2Anchor; diff --git a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts index 28b504089b..6682b429e7 100644 --- a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts +++ b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts @@ -90,6 +90,8 @@ const testSuite = (setup: () => Kit) => { [blockquoteHeader, 16, 16, CommonSliceType.blockquote], ]]); }); + + test.todo('copy only "saved" slices'); }); describe('.import()', () => { @@ -117,6 +119,25 @@ const testSuite = (setup: () => Kit) => { expect(i2.text()).toBe('fghij'); expect(!!i2.attr().bold).toBe(true); }); + + test('can copy a paragraph split', () => { + const kit1 = setup(); + const kit2 = setup(); + kit1.editor.cursor.setAt(5); + kit1.editor.saved.insMarker(CommonSliceType.p); + kit1.editor.cursor.setAt(3, 5); + kit1.peritext.refresh(); + const json = kit1.editor.export(kit1.editor.cursor); + kit2.editor.import(0, json); + kit2.peritext.refresh(); + const json2 = kit2.peritext.blocks.toJson(); + expect(json2).toEqual([ + '', + null, + [CommonSliceType.p, null, 'de'], + [CommonSliceType.p, null, 'fgabcdefghijklmnopqrstuvwxyz'], + ]); + }); }); }; From 86d051e89bb8e9faeb315d66d2a4ecdd1edcd646 Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Sun, 22 Dec 2024 11:22:00 +0100 Subject: [PATCH 3/7] =?UTF-8?q?feat(json-crdt-extensions):=20=F0=9F=8E=B8?= =?UTF-8?q?=20export=20only=20saved=20slices?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/json-crdt-extensions/peritext/editor/Editor.ts | 5 ++++- .../editor/__tests__/Editor-export.spec.ts | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/json-crdt-extensions/peritext/editor/Editor.ts b/src/json-crdt-extensions/peritext/editor/Editor.ts index c2d9088fca..b0f37a1d30 100644 --- a/src/json-crdt-extensions/peritext/editor/Editor.ts +++ b/src/json-crdt-extensions/peritext/editor/Editor.ts @@ -688,9 +688,12 @@ export class Editor implements Printable { const offset = r.start.viewPos(); const viewSlices: ViewSlice[] = []; const view: ViewRange = [text, offset, viewSlices]; - const overlay = this.txt.overlay; + const txt = this.txt; + const overlay = txt.overlay; const slices = overlay.findOverlapping(r); for (const slice of slices) { + const isSavedSlice = slice.id.sid === txt.model.clock.sid; + if (!isSavedSlice) continue; const behavior = slice.behavior; switch (behavior) { case SliceBehavior.One: diff --git a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts index 6682b429e7..c137723721 100644 --- a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts +++ b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts @@ -29,6 +29,18 @@ const testSuite = (setup: () => Kit) => { expect(json).toEqual(['cdefg', 2, [[expect.any(Number), 3, 6, 'bold']]]); }); + test('exports only "saved" slices', () => { + const {editor, peritext} = setup(); + editor.cursor.setAt(3, 3); + editor.local.insOverwrite('italic'); + editor.saved.insOverwrite('bold'); + editor.extra.insOverwrite('underline'); + const range = peritext.rangeAt(2, 5); + peritext.refresh(); + const json = editor.export(range); + expect(json).toEqual(['cdefg', 2, [[expect.any(Number), 3, 6, 'bold']]]); + }); + test('range which start in bold text', () => { const {editor, peritext} = setup(); editor.cursor.setAt(3, 10); @@ -90,8 +102,6 @@ const testSuite = (setup: () => Kit) => { [blockquoteHeader, 16, 16, CommonSliceType.blockquote], ]]); }); - - test.todo('copy only "saved" slices'); }); describe('.import()', () => { From 35f6df25a400735d276e268970daf93189906cac Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Sun, 22 Dec 2024 13:03:54 +0100 Subject: [PATCH 4/7] =?UTF-8?q?fix(json-crdt-extensions):=20=F0=9F=90=9B?= =?UTF-8?q?=20correctly=20compute=20annotations=20endpoints=20in=20import(?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../peritext/editor/Editor.ts | 8 +++++- .../editor/__tests__/Editor-export.spec.ts | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/json-crdt-extensions/peritext/editor/Editor.ts b/src/json-crdt-extensions/peritext/editor/Editor.ts index b0f37a1d30..e43b226df3 100644 --- a/src/json-crdt-extensions/peritext/editor/Editor.ts +++ b/src/json-crdt-extensions/peritext/editor/Editor.ts @@ -761,7 +761,13 @@ export class Editor implements Printable { const anchor1: Anchor = (header & SliceHeaderMask.X1Anchor) >>> SliceHeaderShift.X1Anchor; const anchor2: Anchor = (header & SliceHeaderMask.X2Anchor) >>> SliceHeaderShift.X2Anchor; const behavior: SliceBehavior = (header & SliceHeaderMask.Behavior) >>> SliceHeaderShift.Behavior; - const range = txt.rangeAt(Math.max(0, x1 - offset + pos), x2 - x1); + const x1Src = x1 - offset; + const x2Src = x2 - offset; + const x1Capped = Math.max(0, x1Src); + const x2Capped = Math.min(text.length, x2Src); + const x1Dest = x1Capped + pos; + const annotationLength = x2Capped - x1Capped; + const range = txt.rangeAt(x1Dest, annotationLength); if (anchor1 === Anchor.Before) range.start.refBefore(); else range.start.refAfter(); if (anchor2 === Anchor.Before) range.end.refBefore(); diff --git a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts index c137723721..46dc781efc 100644 --- a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts +++ b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts @@ -130,6 +130,33 @@ const testSuite = (setup: () => Kit) => { expect(!!i2.attr().bold).toBe(true); }); + test('can import a contained annotation', () => { + const kit1 = setup(); + kit1.editor.cursor.setAt(0, 3); + kit1.editor.saved.insOverwrite(CommonSliceType.b); + kit1.peritext.refresh(); + const range = kit1.peritext.rangeAt(1, 1); + const view = kit1.editor.export(range); + kit1.editor.import(5, view); + kit1.peritext.refresh(); + const jsonml = kit1.peritext.blocks.toJson(); + expect(jsonml).toEqual([ + '', + null, + [CommonSliceType.p, expect.any(Object), + [CommonSliceType.b, expect.any(Object), 'abc'], + 'de', + [CommonSliceType.b, expect.any(Object), 'b'], + 'fghijklmnopqrstuvwxyz', + ] + ]); + const block = kit1.peritext.blocks.root.children[0]; + const inlines = [...block.texts()]; + const inline = inlines.find((i) => i.text() === 'b')!; + expect(inline.start.anchor).toBe(Anchor.Before); + expect(inline.end.anchor).toBe(Anchor.After); + }); + test('can copy a paragraph split', () => { const kit1 = setup(); const kit2 = setup(); From b344e1458fe22cbc056554282c10bb1518b41edb Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Sun, 22 Dec 2024 14:48:00 +0100 Subject: [PATCH 5/7] =?UTF-8?q?feat(json-crdt-extensions):=20=F0=9F=8E=B8?= =?UTF-8?q?=20at=20import=20do=20not=20include=20ABS=20start=20in=20annota?= =?UTF-8?q?tion=20range?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../peritext/editor/Editor.ts | 6 +- .../editor/__tests__/Editor-export.spec.ts | 65 +++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/json-crdt-extensions/peritext/editor/Editor.ts b/src/json-crdt-extensions/peritext/editor/Editor.ts index e43b226df3..697e230022 100644 --- a/src/json-crdt-extensions/peritext/editor/Editor.ts +++ b/src/json-crdt-extensions/peritext/editor/Editor.ts @@ -768,10 +768,10 @@ export class Editor implements Printable { const x1Dest = x1Capped + pos; const annotationLength = x2Capped - x1Capped; const range = txt.rangeAt(x1Dest, annotationLength); - if (anchor1 === Anchor.Before) range.start.refBefore(); - else range.start.refAfter(); + if (!!x1Dest && anchor1 === Anchor.After) range.start.refAfter(); + // else range.start.refBefore(); if (anchor2 === Anchor.Before) range.end.refBefore(); - else range.end.refAfter(); + // else range.end.refAfter(); txt.savedSlices.ins(range, behavior, type, data); } } diff --git a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts index 46dc781efc..dfa95bb5b6 100644 --- a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts +++ b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts @@ -157,6 +157,71 @@ const testSuite = (setup: () => Kit) => { expect(inline.end.anchor).toBe(Anchor.After); }); + test('can import a contained annotation (with end edge anchored to neighbor chars)', () => { + const kit1 = setup(); + kit1.editor.cursor.setAt(0, 3); + const start = kit1.editor.cursor.start.clone(); + const end = kit1.editor.cursor.end.clone(); + start.refAfter(); + end.refBefore(); + kit1.editor.cursor.set(start, end); + kit1.editor.saved.insOverwrite(CommonSliceType.b); + kit1.peritext.refresh(); + const range = kit1.peritext.rangeAt(1, 1); + const view = kit1.editor.export(range); + kit1.editor.import(5, view); + kit1.peritext.refresh(); + const jsonml = kit1.peritext.blocks.toJson(); + expect(jsonml).toEqual([ + '', + null, + [CommonSliceType.p, expect.any(Object), + [CommonSliceType.b, expect.any(Object), 'abc'], + 'de', + [CommonSliceType.b, expect.any(Object), 'b'], + 'fghijklmnopqrstuvwxyz', + ] + ]); + const block = kit1.peritext.blocks.root.children[0]; + const inlines = [...block.texts()]; + const inline = inlines.find((i) => i.text() === 'b')!; + expect(inline.start.anchor).toBe(Anchor.After); + expect(inline.end.anchor).toBe(Anchor.Before); + }); + + test('annotation start edge cannot point to ABS start', () => { + const kit1 = setup(); + kit1.editor.cursor.setAt(1, 2); + const start = kit1.editor.cursor.start.clone(); + const end = kit1.editor.cursor.end.clone(); + start.refAfter(); + end.refBefore(); + kit1.editor.cursor.set(start, end); + kit1.editor.saved.insOverwrite(CommonSliceType.b); + kit1.editor.delCursors(); + kit1.peritext.refresh(); + const range = kit1.peritext.rangeAt(1, 1); + const view = kit1.editor.export(range); + kit1.editor.import(0, view); + kit1.peritext.refresh(); + const jsonml = kit1.peritext.blocks.toJson(); + expect(jsonml).toEqual([ + '', + null, + [CommonSliceType.p, expect.any(Object), + [CommonSliceType.b, expect.any(Object), 'b'], + 'a', + [CommonSliceType.b, expect.any(Object), 'bc'], + 'defghijklmnopqrstuvwxyz', + ] + ]); + const block = kit1.peritext.blocks.root.children[0]; + const inlines = [...block.texts()]; + const inline = inlines.find((i) => i.text() === 'b')!; + expect(inline.start.anchor).toBe(Anchor.Before); + expect(inline.end.anchor).toBe(Anchor.Before); + }); + test('can copy a paragraph split', () => { const kit1 = setup(); const kit2 = setup(); From 6bd882ebd9363854cd549ebcbe98c995b0331963 Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Sun, 22 Dec 2024 14:53:30 +0100 Subject: [PATCH 6/7] =?UTF-8?q?feat(json-crdt-extensions):=20=F0=9F=8E=B8?= =?UTF-8?q?=20make=20sure=20annotation=20end=20point=20is=20never=20ABS=20?= =?UTF-8?q?end?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../peritext/editor/Editor.ts | 1 + .../editor/__tests__/Editor-export.spec.ts | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/json-crdt-extensions/peritext/editor/Editor.ts b/src/json-crdt-extensions/peritext/editor/Editor.ts index 697e230022..dd4fe95725 100644 --- a/src/json-crdt-extensions/peritext/editor/Editor.ts +++ b/src/json-crdt-extensions/peritext/editor/Editor.ts @@ -772,6 +772,7 @@ export class Editor implements Printable { // else range.start.refBefore(); if (anchor2 === Anchor.Before) range.end.refBefore(); // else range.end.refAfter(); + if (range.end.isAbs()) range.end.refAfter(); txt.savedSlices.ins(range, behavior, type, data); } } diff --git a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts index dfa95bb5b6..f2d3766ce5 100644 --- a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts +++ b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts @@ -222,6 +222,40 @@ const testSuite = (setup: () => Kit) => { expect(inline.end.anchor).toBe(Anchor.Before); }); + test('annotation end edge cannot point to ABS end', () => { + const kit1 = setup(); + kit1.editor.cursor.setAt(1, 2); + const start = kit1.editor.cursor.start.clone(); + const end = kit1.editor.cursor.end.clone(); + start.refAfter(); + end.refBefore(); + kit1.editor.cursor.set(start, end); + kit1.editor.saved.insOverwrite(CommonSliceType.b); + kit1.editor.delCursors(); + kit1.peritext.refresh(); + const range = kit1.peritext.rangeAt(1, 1); + const view = kit1.editor.export(range); + const length = kit1.peritext.strApi().length(); + kit1.editor.import(length, view); + kit1.peritext.refresh(); + const jsonml = kit1.peritext.blocks.toJson(); + expect(jsonml).toEqual([ + '', + null, + [CommonSliceType.p, expect.any(Object), + 'a', + [CommonSliceType.b, expect.any(Object), 'bc'], + 'defghijklmnopqrstuvwxyz', + [CommonSliceType.b, expect.any(Object), 'b'], + ] + ]); + const block = kit1.peritext.blocks.root.children[0]; + const inlines = [...block.texts()]; + const inline = inlines.find((i) => i.text() === 'b')!; + expect(inline.start.anchor).toBe(Anchor.After); + expect(inline.end.anchor).toBe(Anchor.After); + }); + test('can copy a paragraph split', () => { const kit1 = setup(); const kit2 = setup(); From 6f2988b2cdd68f4d52eb86329be55118ba927be6 Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Sun, 22 Dec 2024 14:53:59 +0100 Subject: [PATCH 7/7] =?UTF-8?q?style(json-crdt-extensions):=20=F0=9F=92=84?= =?UTF-8?q?=20run=20formatter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../peritext/editor/Editor.ts | 5 +- .../editor/__tests__/Editor-export.spec.ts | 54 ++++++++++++------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/json-crdt-extensions/peritext/editor/Editor.ts b/src/json-crdt-extensions/peritext/editor/Editor.ts index dd4fe95725..86fa8d7209 100644 --- a/src/json-crdt-extensions/peritext/editor/Editor.ts +++ b/src/json-crdt-extensions/peritext/editor/Editor.ts @@ -732,8 +732,7 @@ export class Editor implements Printable { texts.push(text.slice(start, end)); start = end + 1; splits.push(slice); - } - else annotations.push(slice); + } else annotations.push(slice); } const lastText = text.slice(start); const splitLength = splits.length; @@ -746,7 +745,7 @@ export class Editor implements Printable { start += str.length; } if (split) { - const [,,, type, data] = split; + const [, , , type, data] = split; const after = txt.pointAt(start); after.refAfter(); txt.savedSlices.insMarkerAfter(after.id, type, data); diff --git a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts index f2d3766ce5..e6b4441749 100644 --- a/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts +++ b/src/json-crdt-extensions/peritext/editor/__tests__/Editor-export.spec.ts @@ -68,12 +68,11 @@ const testSuite = (setup: () => Kit) => { const range = peritext.rangeAt(8, 5); peritext.refresh(); const json = editor.export(range); - const header = (SliceBehavior.Marker << SliceHeaderShift.Behavior) + + const header = + (SliceBehavior.Marker << SliceHeaderShift.Behavior) + (Anchor.Before << SliceHeaderShift.X1Anchor) + (Anchor.Before << SliceHeaderShift.X2Anchor); - expect(json).toEqual(['ij\nkl', 8, [ - [header, 10, 10, CommonSliceType.p] - ]]); + expect(json).toEqual(['ij\nkl', 8, [[header, 10, 10, CommonSliceType.p]]]); }); test('can export

marker,

marker, and italic text', () => { @@ -87,20 +86,27 @@ const testSuite = (setup: () => Kit) => { const range = peritext.rangeAt(8, 12); peritext.refresh(); const json = editor.export(range); - const pHeader = (SliceBehavior.Marker << SliceHeaderShift.Behavior) + + const pHeader = + (SliceBehavior.Marker << SliceHeaderShift.Behavior) + (Anchor.Before << SliceHeaderShift.X1Anchor) + (Anchor.Before << SliceHeaderShift.X2Anchor); - const iHeader = (SliceBehavior.One << SliceHeaderShift.Behavior) + + const iHeader = + (SliceBehavior.One << SliceHeaderShift.Behavior) + (Anchor.Before << SliceHeaderShift.X1Anchor) + (Anchor.After << SliceHeaderShift.X2Anchor); - const blockquoteHeader = (SliceBehavior.Marker << SliceHeaderShift.Behavior) + + const blockquoteHeader = + (SliceBehavior.Marker << SliceHeaderShift.Behavior) + (Anchor.Before << SliceHeaderShift.X1Anchor) + (Anchor.Before << SliceHeaderShift.X2Anchor); - expect(json).toEqual(['ij\nklmno\npqr', 8, [ - [pHeader, 10, 10, CommonSliceType.p], - [iHeader, 12, 14, CommonSliceType.i], - [blockquoteHeader, 16, 16, CommonSliceType.blockquote], - ]]); + expect(json).toEqual([ + 'ij\nklmno\npqr', + 8, + [ + [pHeader, 10, 10, CommonSliceType.p], + [iHeader, 12, 14, CommonSliceType.i], + [blockquoteHeader, 16, 16, CommonSliceType.blockquote], + ], + ]); }); }); @@ -143,12 +149,14 @@ const testSuite = (setup: () => Kit) => { expect(jsonml).toEqual([ '', null, - [CommonSliceType.p, expect.any(Object), + [ + CommonSliceType.p, + expect.any(Object), [CommonSliceType.b, expect.any(Object), 'abc'], 'de', [CommonSliceType.b, expect.any(Object), 'b'], 'fghijklmnopqrstuvwxyz', - ] + ], ]); const block = kit1.peritext.blocks.root.children[0]; const inlines = [...block.texts()]; @@ -175,12 +183,14 @@ const testSuite = (setup: () => Kit) => { expect(jsonml).toEqual([ '', null, - [CommonSliceType.p, expect.any(Object), + [ + CommonSliceType.p, + expect.any(Object), [CommonSliceType.b, expect.any(Object), 'abc'], 'de', [CommonSliceType.b, expect.any(Object), 'b'], 'fghijklmnopqrstuvwxyz', - ] + ], ]); const block = kit1.peritext.blocks.root.children[0]; const inlines = [...block.texts()]; @@ -208,12 +218,14 @@ const testSuite = (setup: () => Kit) => { expect(jsonml).toEqual([ '', null, - [CommonSliceType.p, expect.any(Object), + [ + CommonSliceType.p, + expect.any(Object), [CommonSliceType.b, expect.any(Object), 'b'], 'a', [CommonSliceType.b, expect.any(Object), 'bc'], 'defghijklmnopqrstuvwxyz', - ] + ], ]); const block = kit1.peritext.blocks.root.children[0]; const inlines = [...block.texts()]; @@ -242,12 +254,14 @@ const testSuite = (setup: () => Kit) => { expect(jsonml).toEqual([ '', null, - [CommonSliceType.p, expect.any(Object), + [ + CommonSliceType.p, + expect.any(Object), 'a', [CommonSliceType.b, expect.any(Object), 'bc'], 'defghijklmnopqrstuvwxyz', [CommonSliceType.b, expect.any(Object), 'b'], - ] + ], ]); const block = kit1.peritext.blocks.root.children[0]; const inlines = [...block.texts()];