diff --git a/src/decoration.ts b/src/decoration.ts index 2283224f..4fc3e763 100644 --- a/src/decoration.ts +++ b/src/decoration.ts @@ -550,20 +550,24 @@ function mapChildren( // Mark the children that are directly touched by changes, and // move those that are after the changes. - let shift = (oldStart: number, oldEnd: number, newStart: number, newEnd: number) => { - for (let i = 0; i < children.length; i += 3) { - let end = children[i + 1] as number, dSize - if (end < 0 || oldStart > end + oldOffset) continue - let start = (children[i] as number) + oldOffset - if (oldEnd >= start) { - children[i + 1] = oldStart <= start ? -2 : -1 - } else if (newStart >= offset && (dSize = (newEnd - newStart) - (oldEnd - oldStart))) { - ;(children[i] as number) += dSize - ;(children[i + 1] as number) += dSize + for (let i = 0; i < mapping.maps.length; i++) { + let moved = 0 + mapping.maps[i].forEach((oldStart: number, oldEnd: number, newStart: number, newEnd: number) => { + let dSize = (newEnd - newStart) - (oldEnd - oldStart) + for (let i = 0; i < children.length; i += 3) { + let end = children[i + 1] as number + if (end < 0 || oldStart > end + oldOffset - moved) continue + let start = (children[i] as number) + oldOffset - moved + if (oldEnd >= start) { + children[i + 1] = oldStart <= start ? -2 : -1 + } else if (newStart >= offset && dSize) { + ;(children[i] as number) += dSize + ;(children[i + 1] as number) += dSize + } } - } + moved += dSize + }) } - for (let i = 0; i < mapping.maps.length; i++) mapping.maps[i].forEach(shift) // Find the child nodes that still correspond to a single node, // recursively call mapInner on them and update their positions. diff --git a/test/webtest-decoration.ts b/test/webtest-decoration.ts index 7d9519c2..26620b7a 100644 --- a/test/webtest-decoration.ts +++ b/test/webtest-decoration.ts @@ -286,12 +286,13 @@ describe("DecorationSet", () => { // We want inline decorations to be preserved, so we'll use a custom step that allows this class MyStep extends ReplaceStep { - constructor(from, to, slice, structure, ranges) { + ranges: readonly number[] + constructor(from: number, to: number, slice: Slice, structure: boolean, ranges: readonly number[]) { super(from, to, slice, structure) this.ranges = ranges } getMap() { return new StepMap(this.ranges) } - merge(other) { return null } + merge(other: MyStep) { return null } } const posBeforeFirstWord = di.tag.start - 1 const ranges = [posBeforeFirstWord, 1, 0] // Remove first word's opening token