From 4251c59ceacc6db2ebcadc9d9f865e4024641cbc Mon Sep 17 00:00:00 2001 From: Hackerwins Date: Mon, 20 Nov 2023 17:42:45 +0900 Subject: [PATCH] Remove splitLevels from Tree.Edit --- public/prosemirror.html | 9 +- src/document/crdt/tree.ts | 18 +- src/document/json/tree.ts | 1 - src/document/operation/tree_edit_operation.ts | 1 - test/unit/document/crdt/tree_test.ts | 218 ++++++++---------- 5 files changed, 101 insertions(+), 146 deletions(-) diff --git a/public/prosemirror.html b/public/prosemirror.html index b39855699..0295022d2 100644 --- a/public/prosemirror.html +++ b/public/prosemirror.html @@ -337,10 +337,11 @@

Yorkie.Tree

openEnd && structure ) { - root.tree.edit(from, to, docToTreeNode(node.toJSON()), [ - openStart, - openEnd, - ]); + // TODO(hackerwins): edit should support openStart and openEnd. + // root.tree.edit(from, to, docToTreeNode(node.toJSON()), [ + // openStart, + // openEnd, + // ]); continue; } diff --git a/src/document/crdt/tree.ts b/src/document/crdt/tree.ts index 149f91370..41230f3e9 100644 --- a/src/document/crdt/tree.ts +++ b/src/document/crdt/tree.ts @@ -630,8 +630,6 @@ export class CRDTTree extends CRDTGCElement { public findNodesAndSplit( pos: CRDTTreePos, editedAt: TimeTicket, - /* eslint-disable @typescript-eslint/no-unused-vars */ - splitLevel = 0, ): [CRDTTreeNode, CRDTTreeNode] { // 01. Find the parent and left sibling node of the given position. const [parent, leftSibling] = pos.toTreeNodes(this); @@ -719,21 +717,12 @@ export class CRDTTree extends CRDTGCElement { public edit( range: [CRDTTreePos, CRDTTreePos], contents: Array | undefined, - splitLevels: [number, number], editedAt: TimeTicket, latestCreatedAtMapByActor?: Map, ): [Array, Map] { // 01. split text nodes at the given range if needed. - const [fromParent, fromLeft] = this.findNodesAndSplit( - range[0], - editedAt, - splitLevels[0], - ); - const [toParent, toLeft] = this.findNodesAndSplit( - range[1], - editedAt, - splitLevels[1], - ); + const [fromParent, fromLeft] = this.findNodesAndSplit(range[0], editedAt); + const [toParent, toLeft] = this.findNodesAndSplit(range[1], editedAt); // TODO(hackerwins): If concurrent deletion happens, we need to seperate the // range(from, to) into multiple ranges. @@ -856,12 +845,11 @@ export class CRDTTree extends CRDTGCElement { public editT( range: [number, number], contents: Array | undefined, - splitLevels: [number, number], editedAt: TimeTicket, ): void { const fromPos = this.findPos(range[0]); const toPos = this.findPos(range[1]); - this.edit([fromPos, toPos], contents, splitLevels, editedAt); + this.edit([fromPos, toPos], contents, editedAt); } /** diff --git a/src/document/json/tree.ts b/src/document/json/tree.ts index 195111570..22c4bc022 100644 --- a/src/document/json/tree.ts +++ b/src/document/json/tree.ts @@ -368,7 +368,6 @@ export class Tree { crdtNodes.length ? crdtNodes.map((crdtNode) => crdtNode?.deepcopy()) : undefined, - [0, 0], ticket, ); diff --git a/src/document/operation/tree_edit_operation.ts b/src/document/operation/tree_edit_operation.ts index c9e21f19c..952869457 100644 --- a/src/document/operation/tree_edit_operation.ts +++ b/src/document/operation/tree_edit_operation.ts @@ -89,7 +89,6 @@ export class TreeEditOperation extends Operation { const [changes] = tree.edit( [this.fromPos, this.toPos], this.contents?.map((content) => content.deepcopy()), - [0, 0], this.getExecutedAt(), this.maxCreatedAtMapByActor, ); diff --git a/test/unit/document/crdt/tree_test.ts b/test/unit/document/crdt/tree_test.ts index 8bd1a390c..b52bc4215 100644 --- a/test/unit/document/crdt/tree_test.ts +++ b/test/unit/document/crdt/tree_test.ts @@ -102,18 +102,13 @@ describe('CRDTTree.Edit', function () { // 1 //

- t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); assert.equal(t.toXML(), /*html*/ `

`); assert.equal(t.getRoot().size, 2); // 1 //

h e l l o

- t.editT( - [1, 1], - [new CRDTTreeNode(posT(), 'text', 'hello')], - [0, 0], - timeT(), - ); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'hello')], timeT()); assert.equal(t.toXML(), /*html*/ `

hello

`); assert.equal(t.getRoot().size, 7); @@ -121,13 +116,13 @@ describe('CRDTTree.Edit', function () { //

h e l l o

w o r l d

const p = new CRDTTreeNode(posT(), 'p', []); p.insertAt(new CRDTTreeNode(posT(), 'text', 'world'), 0); - t.editT([7, 7], [p], [0, 0], timeT()); + t.editT([7, 7], [p], timeT()); assert.equal(t.toXML(), /*html*/ `

hello

world

`); assert.equal(t.getRoot().size, 14); // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //

h e l l o !

w o r l d

- t.editT([6, 6], [new CRDTTreeNode(posT(), 'text', '!')], [0, 0], timeT()); + t.editT([6, 6], [new CRDTTreeNode(posT(), 'text', '!')], timeT()); assert.equal(t.toXML(), /*html*/ `

hello!

world

`); assert.deepEqual(t.toTestTreeNode(), { @@ -157,7 +152,7 @@ describe('CRDTTree.Edit', function () { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //

h e l l o ~ !

w o r l d

- t.editT([6, 6], [new CRDTTreeNode(posT(), 'text', '~')], [0, 0], timeT()); + t.editT([6, 6], [new CRDTTreeNode(posT(), 'text', '~')], timeT()); assert.equal(t.toXML(), /*html*/ `

hello~!

world

`); }); @@ -166,20 +161,10 @@ describe('CRDTTree.Edit', function () { // 0 1 2 3 4 5 6 7 8 //

a b

c d

const tree = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - tree.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - tree.editT( - [1, 1], - [new CRDTTreeNode(posT(), 'text', 'ab')], - [0, 0], - timeT(), - ); - tree.editT([4, 4], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - tree.editT( - [5, 5], - [new CRDTTreeNode(posT(), 'text', 'cd')], - [0, 0], - timeT(), - ); + tree.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + tree.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); + tree.editT([4, 4], [new CRDTTreeNode(posT(), 'p')], timeT()); + tree.editT([5, 5], [new CRDTTreeNode(posT(), 'text', 'cd')], timeT()); assert.deepEqual(tree.toXML(), /*html*/ `

ab

cd

`); let treeNode = tree.toTestTreeNode(); @@ -190,7 +175,7 @@ describe('CRDTTree.Edit', function () { // 02. delete b from first paragraph // 0 1 2 3 4 5 6 7 //

a

c d

- tree.editT([2, 3], undefined, [0, 0], timeT()); + tree.editT([2, 3], undefined, timeT()); assert.deepEqual(tree.toXML(), /*html*/ `

a

cd

`); treeNode = tree.toTestTreeNode(); @@ -207,33 +192,31 @@ describe('CRDTTree.Edit', function () { // 0 1 2 3 4 //

a b

- t.editT([0, 0], [pNode], [0, 0], timeT()); - t.editT([1, 1], [textNode], [0, 0], timeT()); + t.editT([0, 0], [pNode], timeT()); + t.editT([1, 1], [textNode], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); // Find the closest index.TreePos when leftSiblingNode in crdt.TreePos is removed. // 0 1 2 //

- t.editT([1, 3], undefined, [0, 0], timeT()); + t.editT([1, 3], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

`); let [parent, left] = t.findNodesAndSplit( new CRDTTreePos(pNode.id, textNode.id), timeT(), - 0, ); assert.equal(t.toIndex(parent, left), 1); // Find the closest index.TreePos when parentNode in crdt.TreePos is removed. // 0 // - t.editT([0, 2], undefined, [0, 0], timeT()); + t.editT([0, 2], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ ``); [parent, left] = t.findNodesAndSplit( new CRDTTreePos(pNode.id, textNode.id), timeT(), - 0, ); assert.equal(t.toIndex(parent, left), 0); }); @@ -245,13 +228,8 @@ describe('CRDTTree.Split', function () { // 0 1 6 11 //

hello world

const t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT( - [1, 1], - [new CRDTTreeNode(posT(), 'text', 'helloworld')], - [0, 0], - timeT(), - ); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'helloworld')], timeT()); const expectedIntial = { type: 'root', children: [ @@ -270,15 +248,15 @@ describe('CRDTTree.Split', function () { assert.deepEqual(t.toTestTreeNode(), expectedIntial); // 01. Split left side of 'helloworld'. - t.editT([1, 1], undefined, [0, 0], timeT()); + t.editT([1, 1], undefined, timeT()); assert.deepEqual(t.toTestTreeNode(), expectedIntial); // 02. Split right side of 'helloworld'. - t.editT([11, 11], undefined, [0, 0], timeT()); + t.editT([11, 11], undefined, timeT()); assert.deepEqual(t.toTestTreeNode(), expectedIntial); // 03. Split 'helloworld' into 'hello' and 'world'. - t.editT([6, 6], undefined, [0, 0], timeT()); + t.editT([6, 6], undefined, timeT()); assert.deepEqual(t.toTestTreeNode(), { type: 'root', children: [ @@ -303,28 +281,28 @@ describe('CRDTTree.Split', function () { // 01. Split position 1. let t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); - t.editT([1, 1], undefined, [1, 1], timeT()); + // t.editT([1, 1], undefined, [1, 1], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); assert.equal(t.getSize(), 6); // 02. Split position 2. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); - t.editT([2, 2], undefined, [1, 1], timeT()); + // t.editT([2, 2], undefined, [1, 1], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

a

b

`); assert.equal(t.getSize(), 6); // 03. Split position 3. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); - t.editT([3, 3], undefined, [1, 1], timeT()); + // t.editT([3, 3], undefined, [1, 1], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); assert.equal(t.getSize(), 6); }); @@ -335,11 +313,11 @@ describe('CRDTTree.Split', function () { // 01. Split nodes level 1. let t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); - t.editT([3, 3], undefined, [1, 1], timeT()); + // t.editT([3, 3], undefined, [1, 1], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

`, @@ -347,11 +325,11 @@ describe('CRDTTree.Split', function () { // 02. Split nodes level 2. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); - t.editT([3, 3], undefined, [2, 2], timeT()); + // t.editT([3, 3], undefined, [2, 2], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

a

b

`, @@ -359,11 +337,11 @@ describe('CRDTTree.Split', function () { // Split multiple nodes level 3. But, it is allowed to split only level 2. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); - t.editT([3, 3], undefined, [3, 3], timeT()); + // t.editT([3, 3], undefined, [3, 3], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

a

b

`, @@ -372,13 +350,8 @@ describe('CRDTTree.Split', function () { it.skip('Can split and merge element nodes by edit', function () { const t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT( - [1, 1], - [new CRDTTreeNode(posT(), 'text', 'abcd')], - [0, 0], - timeT(), - ); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'abcd')], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

abcd

`); assert.equal(t.getSize(), 6); @@ -388,7 +361,7 @@ describe('CRDTTree.Split', function () { assert.deepEqual(t.toXML(), /*html*/ `

ab

cd

`); assert.equal(t.getSize(), 8); - t.editT([3, 5], undefined, [0, 0], timeT()); + t.editT([3, 5], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

abcd

`); assert.equal(t.getSize(), 6); }); @@ -400,16 +373,16 @@ describe('CRDTTree.Merge', function () { // 0 1 2 3 4 5 6 7 8 //

a b

c d

const t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); - t.editT([4, 4], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([5, 5], [new CRDTTreeNode(posT(), 'text', 'cd')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); + t.editT([4, 4], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([5, 5], [new CRDTTreeNode(posT(), 'text', 'cd')], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

cd

`); // 02. delete b, c and the second paragraph. // 0 1 2 3 4 //

a d

- t.editT([2, 6], undefined, [0, 0], timeT()); + t.editT([2, 6], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ad

`); const node = t.toTestTreeNode(); @@ -419,7 +392,7 @@ describe('CRDTTree.Merge', function () { assert.equal(node.children![0].children![1].size, 1); // d // 03. insert a new text node at the start of the first paragraph. - t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', '@')], [0, 0], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', '@')], timeT()); assert.deepEqual(t.toXML(), /*html*/ `

@ad

`); }); @@ -428,11 +401,11 @@ describe('CRDTTree.Merge', function () { // 0 1 2 3 4 5 6 7 8 9 10 //

a b

c d

const t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); - t.editT([6, 6], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([7, 7], [new CRDTTreeNode(posT(), 'text', 'cd')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); + t.editT([6, 6], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([7, 7], [new CRDTTreeNode(posT(), 'text', 'cd')], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

cd

`, @@ -441,7 +414,7 @@ describe('CRDTTree.Merge', function () { // 02. delete b, c and second paragraph. // 0 1 2 3 4 5 //

a d - t.editT([3, 8], undefined, [0, 0], timeT()); + t.editT([3, 8], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ad

`); }); @@ -451,101 +424,96 @@ describe('CRDTTree.Merge', function () { // 0 1 2 3 4 5 6 7 8 //

a b

let t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], [0, 0], timeT()); - t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], timeT()); + t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

`, ); - t.editT([5, 6], undefined, [0, 0], timeT()); + t.editT([5, 6], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); // 02. edit between two element nodes in same hierarchy. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], [0, 0], timeT()); - t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], timeT()); + t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

`, ); - t.editT([6, 7], undefined, [0, 0], timeT()); + t.editT([6, 7], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); // 03. edit between text and element node in same hierarchy. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], [0, 0], timeT()); - t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], timeT()); + t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

`, ); - t.editT([4, 6], undefined, [0, 0], timeT()); + t.editT([4, 6], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

a

`); // 04. edit between text and element node in same hierarchy. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], [0, 0], timeT()); - t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], timeT()); + t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

`, ); - t.editT([5, 7], undefined, [0, 0], timeT()); + t.editT([5, 7], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

ab

`); // 05. edit between text and element node in same hierarchy. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], [0, 0], timeT()); - t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], timeT()); + t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

`, ); - t.editT([4, 7], undefined, [0, 0], timeT()); + t.editT([4, 7], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

a

`); // 06. edit between text and element node in same hierarchy. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], [0, 0], timeT()); - t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([2, 2], [new CRDTTreeNode(posT(), 'i')], timeT()); + t.editT([3, 3], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

`, ); - t.editT([3, 7], undefined, [0, 0], timeT()); + t.editT([3, 7], undefined, timeT()); assert.deepEqual(t.toXML(), /*html*/ `

`); // 07. edit between text and element node in same hierarchy. t = new CRDTTree(new CRDTTreeNode(posT(), 'root'), timeT()); - t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], [0, 0], timeT()); - t.editT([4, 4], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT([5, 5], [new CRDTTreeNode(posT(), 'b')], [0, 0], timeT()); - t.editT([6, 6], [new CRDTTreeNode(posT(), 'text', 'cd')], [0, 0], timeT()); - t.editT([10, 10], [new CRDTTreeNode(posT(), 'p')], [0, 0], timeT()); - t.editT( - [11, 11], - [new CRDTTreeNode(posT(), 'text', 'ef')], - [0, 0], - timeT(), - ); + t.editT([0, 0], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([1, 1], [new CRDTTreeNode(posT(), 'text', 'ab')], timeT()); + t.editT([4, 4], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([5, 5], [new CRDTTreeNode(posT(), 'b')], timeT()); + t.editT([6, 6], [new CRDTTreeNode(posT(), 'text', 'cd')], timeT()); + t.editT([10, 10], [new CRDTTreeNode(posT(), 'p')], timeT()); + t.editT([11, 11], [new CRDTTreeNode(posT(), 'text', 'ef')], timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

cd

ef

`, ); - t.editT([9, 10], undefined, [0, 0], timeT()); + t.editT([9, 10], undefined, timeT()); assert.deepEqual( t.toXML(), /*html*/ `

ab

cd

ef

`,