diff --git a/src/json-patch-ot/__tests__/scenarios.spec.ts b/src/json-patch-ot/__tests__/scenarios.spec.ts index 3b9d41bc64..be82dcbc01 100644 --- a/src/json-patch-ot/__tests__/scenarios.spec.ts +++ b/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'}, }, + { + // discard multiple same inserts (will typically happen in markdown task lists) + name: 'Inserts the same into same string at the 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/src/json-patch-ot/transforms/xStrIns.ts b/src/json-patch-ot/transforms/xStrIns.ts index 17d2d3d3d0..afe636645e 100644 --- a/src/json-patch-ot/transforms/xStrIns.ts +++ b/src/json-patch-ot/transforms/xStrIns.ts @@ -4,6 +4,7 @@ import {type Op, OpStrDel, OpStrIns} from '../../json-patch/op'; export const xStrIns = (ins: OpStrIns, op: Op): null | Op | Op[] => { if (op instanceof OpStrIns) { if (ins.pos > op.pos) return op; + if (ins.pos === op.pos && ins.str === op.str) return null; // discard equal inserts return operationToOp({...op.toJson(), pos: op.pos + ins.str.length}, {}); } else if (op instanceof OpStrDel) { const del = op;