fix backwards edge case

This commit is contained in:
Kevin Jahns 2021-11-21 14:00:02 +01:00
parent 4a8ebc31f7
commit 40c3be1732
2 changed files with 31 additions and 13 deletions

View File

@ -54,7 +54,21 @@ export const useSearchMarker = (tr, yarray, index, f) => {
if (createFreshMarker) { if (createFreshMarker) {
searchMarker.push(fsm) searchMarker.push(fsm)
} }
const diff = fsm.index - index
if (diff > 0) {
fsm.backward(tr, diff)
} else {
fsm.forward(tr, -diff)
}
const result = f(fsm) const result = f(fsm)
if (fsm.reachedEnd) {
fsm.reachedEnd = false
const nextItem = /** @type {Item} */ (fsm.nextItem)
if (nextItem.countable && !nextItem.deleted) {
fsm.index -= nextItem.length
}
fsm.rel = 0
}
if (!createFreshMarker && fsm.nextItem !== prevItem) { if (!createFreshMarker && fsm.nextItem !== prevItem) {
// reused old marker and we moved to a different position // reused old marker and we moved to a different position
prevItem.marker = false prevItem.marker = false
@ -76,22 +90,25 @@ export const useSearchMarker = (tr, yarray, index, f) => {
* *
* This should be called before doing a deletion! * This should be called before doing a deletion!
* *
* @param {Transaction} tr
* @param {Array<ListIterator>} searchMarker * @param {Array<ListIterator>} searchMarker
* @param {number} index * @param {number} index
* @param {number} len If insertion, len is positive. If deletion, len is negative. * @param {number} len If insertion, len is positive. If deletion, len is negative.
* @param {ListIterator} origSearchMarker Do not update this searchmarker because it is the one we used to manipulate.
*/ */
export const updateMarkerChanges = (tr, searchMarker, index, len) => { export const updateMarkerChanges = (searchMarker, index, len, origSearchMarker) => {
for (let i = searchMarker.length - 1; i >= 0; i--) { for (let i = searchMarker.length - 1; i >= 0; i--) {
const marker = searchMarker[i] const marker = searchMarker[i]
if (len > 0 && index === marker.index) { if (marker !== origSearchMarker) {
// inserting at a marked position deletes the marked position because we can't do a simple transformation if (len > 0 && index === marker.index) {
// (we don't know whether to insert directly before or directly after the position) // inserting at a marked position deletes the marked position because we can't do a simple transformation
searchMarker.splice(i, 1) // (we don't know whether to insert directly before or directly after the position)
continue searchMarker.splice(i, 1)
} if (marker.nextItem) marker.nextItem.marker = false
if (index < marker.index) { // a simple index <= m.index check would actually suffice continue
marker.index = math.max(index, marker.index + len) }
if (index < marker.index) { // a simple index <= m.index check would actually suffice
marker.index = math.max(index, marker.index + len)
}
} }
} }
} }

View File

@ -202,7 +202,7 @@ export class ListIterator {
item = item.left item = item.left
} }
this.index -= len this.index -= len
this.nextItem = item this.nextItem = item && item.right
return this return this
} }
@ -278,11 +278,12 @@ export class ListIterator {
if (item && !this.reachedEnd && len > 0) { if (item && !this.reachedEnd && len > 0) {
this.nextItem = item this.nextItem = item
this.forward(tr, 0) this.forward(tr, 0)
item = this.nextItem
} }
} }
this.nextItem = item this.nextItem = item
if (sm) { if (sm) {
updateMarkerChanges(tr, sm, this.index, -startLength + len) updateMarkerChanges(sm, this.index, -startLength + len, this)
} }
} }
@ -369,7 +370,7 @@ export class ListIterator {
this.nextItem = right this.nextItem = right
} }
if (sm) { if (sm) {
updateMarkerChanges(tr, sm, this.index, content.length) updateMarkerChanges(sm, this.index, content.length, this)
} }
this.index += content.length this.index += content.length
} }