diff --git a/packages/json-joy/src/json-patch-ot/__tests__/scenarios.spec.ts b/packages/json-joy/src/json-patch-ot/__tests__/scenarios.spec.ts index 795694e9ff..00b5ba16cb 100644 --- a/packages/json-joy/src/json-patch-ot/__tests__/scenarios.spec.ts +++ b/packages/json-joy/src/json-patch-ot/__tests__/scenarios.spec.ts @@ -785,6 +785,14 @@ const groups: ScenarioGroup[] = [ user2: [{op: 'str_ins', path: '/a', pos: 2, str: '_bar_'}], docEnd: {a: '12_foo__bar_345'}, }, + { + // changed: discard multiple same inserts (will typically happen in markdown task lists) + name: 'Merge equal inserts at same position.', + docStart: {a: '12345'}, + user1: [{op: 'str_ins', path: '/a', pos: 2, str: '_foo_'}], + user2: [{op: 'str_ins', path: '/a', pos: 2, str: '_foo_'}], + docEnd: {a: '12_foo_345'}, + }, ], }, { diff --git a/packages/json-joy/src/json-patch-ot/transforms/xStrIns.ts b/packages/json-joy/src/json-patch-ot/transforms/xStrIns.ts index 9bd76e0a8a..ba482cbf75 100644 --- a/packages/json-joy/src/json-patch-ot/transforms/xStrIns.ts +++ b/packages/json-joy/src/json-patch-ot/transforms/xStrIns.ts @@ -6,6 +6,7 @@ export const xStrIns = (ins: OpStrIns, op: Op): null | Op | Op[] => { if (op instanceof OpStrIns) { if (!isPathEqual(ins.path, op.path)) return op; if (ins.pos > op.pos) return op; + if (ins.pos === op.pos && ins.str === op.str) return null; return operationToOp({...op.toJson(), pos: op.pos + ins.str.length}, {}); } else if (op instanceof OpStrDel) { if (!isPathEqual(ins.path, op.path)) return op;