normalize ranges
This commit is contained in:
parent
44499cb9fe
commit
ab5061cd47
@ -9,7 +9,7 @@ import {
|
|||||||
import { decodeRelativePosition, encodeRelativePosition } from 'yjs'
|
import { decodeRelativePosition, encodeRelativePosition } from 'yjs'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ContentMove} moved
|
* @param {ContentMove | { start: RelativePosition, end: RelativePosition }} moved
|
||||||
* @param {Transaction} tr
|
* @param {Transaction} tr
|
||||||
* @return {{ start: Item, end: Item }} $start (inclusive) is the beginning and $end (inclusive) is the end of the moved area
|
* @return {{ start: Item, end: Item }} $start (inclusive) is the beginning and $end (inclusive) is the end of the moved area
|
||||||
*/
|
*/
|
||||||
|
@ -616,7 +616,7 @@ export const getMinimalListViewRanges = (tr, walker, len) => {
|
|||||||
walker.reduceMoveDepth(tr)
|
walker.reduceMoveDepth(tr)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Array<{ start: RelativePosition, end: RelativePosition }>}
|
* @type {Array<{ start: RelativePosition, end: RelativePosition, move: Item | null }>}
|
||||||
*/
|
*/
|
||||||
const ranges = []
|
const ranges = []
|
||||||
// store relevant information for the beginning, before we iterate forward
|
// store relevant information for the beginning, before we iterate forward
|
||||||
@ -677,6 +677,7 @@ export const getMinimalListViewRanges = (tr, walker, len) => {
|
|||||||
preStack.shift()
|
preStack.shift()
|
||||||
afterStack.shift()
|
afterStack.shift()
|
||||||
}
|
}
|
||||||
|
const topLevelMove = preStack.length > 0 ? preStack[0].moved : (afterStack.length > 0 ? afterStack[0].moved : null)
|
||||||
|
|
||||||
// remove stack-items that are useless for our computation (that wouldn't produce meaningful ranges)
|
// remove stack-items that are useless for our computation (that wouldn't produce meaningful ranges)
|
||||||
// @todo
|
// @todo
|
||||||
@ -685,19 +686,21 @@ export const getMinimalListViewRanges = (tr, walker, len) => {
|
|||||||
const move = /** @type {Item} */ (preStack.pop())
|
const move = /** @type {Item} */ (preStack.pop())
|
||||||
ranges.push({
|
ranges.push({
|
||||||
start,
|
start,
|
||||||
end: /** @type {ContentMove} */ (move.content).end
|
end: /** @type {ContentMove} */ (move.content).end,
|
||||||
|
move
|
||||||
})
|
})
|
||||||
start = createRelativePosition(walker.type, createID(move.id.client, move.id.clock), -1)
|
start = createRelativePosition(walker.type, createID(move.id.client, move.id.clock), -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const middleMove = { start, end }
|
const middleMove = { start, end, move: topLevelMove }
|
||||||
ranges.push(middleMove)
|
ranges.push(middleMove)
|
||||||
|
|
||||||
while (afterStack.length > 0) {
|
while (afterStack.length > 0) {
|
||||||
const move = /** @type {Item} */ (afterStack.pop())
|
const move = /** @type {Item} */ (afterStack.pop())
|
||||||
ranges.push({
|
ranges.push({
|
||||||
start: /** @type {ContentMove} */ (move.content).start,
|
start: /** @type {ContentMove} */ (move.content).start,
|
||||||
end
|
end,
|
||||||
|
move
|
||||||
})
|
})
|
||||||
end = createRelativePosition(walker.type, createID(move.id.client, move.id.clock), 0)
|
end = createRelativePosition(walker.type, createID(move.id.client, move.id.clock), 0)
|
||||||
}
|
}
|
||||||
@ -706,6 +709,40 @@ export const getMinimalListViewRanges = (tr, walker, len) => {
|
|||||||
// Move ranges must be applied in order
|
// Move ranges must be applied in order
|
||||||
middleMove.end = end
|
middleMove.end = end
|
||||||
|
|
||||||
|
const normalizedRanges = ranges.map(range => {
|
||||||
|
// A subset of a range could be moved by another move with a higher priority.
|
||||||
|
// If that is the case, we need to ignore those moved items.
|
||||||
|
const { start, end } = getMovedCoords(range, tr)
|
||||||
|
const move = range.move
|
||||||
|
const ranges = []
|
||||||
|
/**
|
||||||
|
* @type {RelativePosition | null}
|
||||||
|
*/
|
||||||
|
let rangeStart = range.start
|
||||||
|
/**
|
||||||
|
* @type {Item}
|
||||||
|
*/
|
||||||
|
let item = start
|
||||||
|
while (item !== end) {
|
||||||
|
if (item.moved !== move && rangeStart != null) {
|
||||||
|
ranges.push({ start: rangeStart, end: createRelativePosition(walker.type, createID(item.id.client, item.id.clock), 0) })
|
||||||
|
rangeStart = null
|
||||||
|
}
|
||||||
|
if (item.moved === move && rangeStart === null) {
|
||||||
|
// @todo It might be better to set this to item.left, with assoc -1
|
||||||
|
rangeStart = createRelativePosition(walker.type, createID(item.id.client, item.id.clock), 0)
|
||||||
|
}
|
||||||
|
item = /** @type {Item} */ (item.right)
|
||||||
|
}
|
||||||
|
if (rangeStart != null) {
|
||||||
|
ranges.push({
|
||||||
|
start: rangeStart,
|
||||||
|
end: range.end
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ranges
|
||||||
|
}).flat()
|
||||||
|
|
||||||
// filter out unnecessary ranges
|
// filter out unnecessary ranges
|
||||||
return ranges.filter(range => !compareRelativePositions(range.start, range.end))
|
return normalizedRanges.filter(range => !compareRelativePositions(range.start, range.end))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user