|
@@ -80,8 +80,6 @@ const RangesManager = {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- sanityCheckTrackedChanges(projectId, docId, rangesTracker.changes)
|
|
|
|
|
-
|
|
|
|
|
if (
|
|
if (
|
|
|
rangesTracker.changes?.length > RangesManager.MAX_CHANGES ||
|
|
rangesTracker.changes?.length > RangesManager.MAX_CHANGES ||
|
|
|
rangesTracker.comments?.length > RangesManager.MAX_COMMENTS
|
|
rangesTracker.comments?.length > RangesManager.MAX_COMMENTS
|
|
@@ -129,12 +127,11 @@ const RangesManager = {
|
|
|
return { newRanges, rangesWereCollapsed, historyUpdates }
|
|
return { newRanges, rangesWereCollapsed, historyUpdates }
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- acceptChanges(projectId, docId, changeIds, ranges) {
|
|
|
|
|
|
|
+ acceptChanges(changeIds, ranges) {
|
|
|
const { changes, comments } = ranges
|
|
const { changes, comments } = ranges
|
|
|
logger.debug(`accepting ${changeIds.length} changes in ranges`)
|
|
logger.debug(`accepting ${changeIds.length} changes in ranges`)
|
|
|
const rangesTracker = new RangesTracker(changes, comments)
|
|
const rangesTracker = new RangesTracker(changes, comments)
|
|
|
rangesTracker.removeChangeIds(changeIds)
|
|
rangesTracker.removeChangeIds(changeIds)
|
|
|
- sanityCheckTrackedChanges(projectId, docId, rangesTracker.changes)
|
|
|
|
|
const newRanges = RangesManager._getRanges(rangesTracker)
|
|
const newRanges = RangesManager._getRanges(rangesTracker)
|
|
|
return newRanges
|
|
return newRanges
|
|
|
},
|
|
},
|
|
@@ -560,66 +557,4 @@ function getCroppedCommentOps(op, comments) {
|
|
|
return historyCommentOps
|
|
return historyCommentOps
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * Check some tracked changes assumptions:
|
|
|
|
|
- *
|
|
|
|
|
- * - Tracked changes can't be empty
|
|
|
|
|
- * - Tracked inserts can't overlap with another tracked change
|
|
|
|
|
- * - There can't be two tracked deletes at the same position
|
|
|
|
|
- * - Ranges should be ordered by position, deletes before inserts
|
|
|
|
|
- * - Every tracked change id should be unique
|
|
|
|
|
- *
|
|
|
|
|
- * If any assumption isn't upheld, log a warning.
|
|
|
|
|
- *
|
|
|
|
|
- * @param {string} projectId
|
|
|
|
|
- * @param {string} docId
|
|
|
|
|
- * @param {TrackedChange[]} changes
|
|
|
|
|
- */
|
|
|
|
|
-function sanityCheckTrackedChanges(projectId, docId, changes) {
|
|
|
|
|
- const idsSeen = new Set()
|
|
|
|
|
- let lastDeletePos = -1 // allow a tracked delete at position 0
|
|
|
|
|
- let lastInsertEnd = 0
|
|
|
|
|
- let ok = true
|
|
|
|
|
- for (const change of changes) {
|
|
|
|
|
- if (idsSeen.has(change.id)) {
|
|
|
|
|
- ok = false
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
- idsSeen.add(change.id)
|
|
|
|
|
-
|
|
|
|
|
- const op = change.op
|
|
|
|
|
- if ('i' in op) {
|
|
|
|
|
- if (op.i.length === 0 || op.p < lastDeletePos || op.p < lastInsertEnd) {
|
|
|
|
|
- ok = false
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
- lastInsertEnd = op.p + op.i.length
|
|
|
|
|
- } else if ('d' in op) {
|
|
|
|
|
- if (op.d.length === 0 || op.p <= lastDeletePos || op.p < lastInsertEnd) {
|
|
|
|
|
- ok = false
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
- lastDeletePos = op.p
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (ok) {
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const changeRanges = []
|
|
|
|
|
- for (const change of changes) {
|
|
|
|
|
- if ('i' in change.op) {
|
|
|
|
|
- changeRanges.push({ p: change.op.p, i: change.op.i.length })
|
|
|
|
|
- } else if ('d' in change.op) {
|
|
|
|
|
- changeRanges.push({ p: change.op.p, d: change.op.d.length })
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- logger.warn(
|
|
|
|
|
- { projectId, docId, changes: changeRanges },
|
|
|
|
|
- 'Malformed tracked changes detected'
|
|
|
|
|
- )
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
module.exports = RangesManager
|
|
module.exports = RangesManager
|