handle nested moves
This commit is contained in:
@@ -122,7 +122,7 @@ export class ListIterator {
|
||||
len += this.rel
|
||||
this.rel = 0
|
||||
}
|
||||
while (item && !this.reachedEnd && (len > 0 || (len === 0 && (!item.countable || item.deleted || item === this.currMoveEnd)))) {
|
||||
while (item && !this.reachedEnd && (len > 0 || (len === 0 && (!item.countable || item.deleted || item === this.currMoveEnd || item.moved !== this.currMove)))) {
|
||||
if (item.countable && !item.deleted && item.moved === this.currMove && len > 0) {
|
||||
len -= item.length
|
||||
if (len < 0) {
|
||||
@@ -350,7 +350,7 @@ export class ListIterator {
|
||||
* @param {RelativePosition} end
|
||||
*/
|
||||
insertMove (tr, start, end) {
|
||||
this.insertContents(tr, [new ContentMove(start, end, 1)]) // @todo adjust priority
|
||||
this.insertContents(tr, [new ContentMove(start, end, -1)]) // @todo adjust priority
|
||||
// @todo is there a better alrogirthm to update searchmarkers? We could simply remove the markers that are in the updated range.
|
||||
// Also note that searchmarkers are updated in insertContents as well.
|
||||
const sm = this.type._searchMarker
|
||||
|
||||
@@ -9,6 +9,8 @@ import {
|
||||
createID,
|
||||
ContentType,
|
||||
followRedone,
|
||||
transact,
|
||||
useSearchMarker,
|
||||
ID, Doc, AbstractType // eslint-disable-line
|
||||
} from '../internals.js'
|
||||
|
||||
@@ -161,7 +163,6 @@ export const createRelativePosition = (type, item, assoc) => {
|
||||
* @function
|
||||
*/
|
||||
export const createRelativePositionFromTypeIndex = (type, index, assoc = 0) => {
|
||||
let t = type._start
|
||||
if (assoc < 0) {
|
||||
// associated to the left character or the beginning of a type, increment index if possible.
|
||||
if (index === 0) {
|
||||
@@ -169,21 +170,17 @@ export const createRelativePositionFromTypeIndex = (type, index, assoc = 0) => {
|
||||
}
|
||||
index--
|
||||
}
|
||||
while (t !== null) {
|
||||
if (!t.deleted && t.countable) {
|
||||
if (t.length > index) {
|
||||
// case 1: found position somewhere in the linked list
|
||||
return createRelativePosition(type, createID(t.id.client, t.id.clock + index), assoc)
|
||||
return transact(/** @type {Doc} */ (type.doc), tr =>
|
||||
useSearchMarker(tr, type, index, walker => {
|
||||
if (walker.reachedEnd) {
|
||||
const item = assoc < 0 ? /** @type {Item} */ (walker.nextItem).lastId : null
|
||||
return createRelativePosition(type, item, assoc)
|
||||
} else {
|
||||
const id = /** @type {Item} */ (walker.nextItem).id
|
||||
return createRelativePosition(type, createID(id.client, id.clock + walker.rel), assoc)
|
||||
}
|
||||
index -= t.length
|
||||
}
|
||||
if (t.right === null && assoc < 0) {
|
||||
// left-associated position, return last available id
|
||||
return createRelativePosition(type, t.lastId, assoc)
|
||||
}
|
||||
t = t.right
|
||||
}
|
||||
return createRelativePosition(type, null, assoc)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -114,6 +114,14 @@ export class Transaction {
|
||||
* @type {Set<Doc>}
|
||||
*/
|
||||
this.subdocsLoaded = new Set()
|
||||
/**
|
||||
* We store the reference that last moved an item.
|
||||
* This is needed to compute the delta when multiple ContentMove move
|
||||
* the same item.
|
||||
*
|
||||
* @type {Map<Item, Item>}
|
||||
*/
|
||||
this.prevMoved = new Map()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ export class YEvent {
|
||||
continue // do not move to item.right
|
||||
}
|
||||
} else if (item.moved !== currMove) {
|
||||
if (!currMoveIsNew && item.countable && !this.adds(item)) {
|
||||
if (!currMoveIsNew && item.countable && !this.adds(item) && (this.transaction.prevMoved.get(item) || null) === currMove) {
|
||||
if (lastOp === null || lastOp.delete === undefined) {
|
||||
packOp()
|
||||
lastOp = { delete: 0 }
|
||||
|
||||
Reference in New Issue
Block a user