mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Merge pull request #35982 from overleaf/mg-history-ot-comments
HistoryOT - Fix comments being dropped and crashing on detached ranges GitOrigin-RevId: 0906a55a51a6fda9ac828efcbe72989573161261
This commit is contained in:
@@ -126,6 +126,25 @@ class EditOperationTransformer {
|
||||
`Transform not implemented for ${a.constructor.name}○${b.constructor.name}`
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform each operation in `as` against each operation in `bs`, priming
|
||||
* both lists in place.
|
||||
* @param {EditOperation[]} as - modified in place
|
||||
* @param {EditOperation[]} bs - modified in place
|
||||
*/
|
||||
static transformMultiple(as, bs) {
|
||||
for (let i = 0; i < as.length; ++i) {
|
||||
for (let j = 0; j < bs.length; ++j) {
|
||||
const [aPrime, bPrime] = EditOperationTransformer.transform(
|
||||
as[i],
|
||||
bs[j]
|
||||
)
|
||||
as[i] = aPrime
|
||||
bs[j] = bPrime
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,6 +10,7 @@ const DeleteCommentOperation = require('../../lib/operation/delete_comment_opera
|
||||
const SetCommentStateOperation = require('../../lib/operation/set_comment_state_operation')
|
||||
const Range = require('../../lib/range')
|
||||
const EditNoOperation = require('../../lib/operation/edit_no_operation')
|
||||
const StringFileData = require('../../lib/file_data/string_file_data')
|
||||
|
||||
describe('EditOperation', function () {
|
||||
it('Cannot be instantiated', function () {
|
||||
@@ -246,6 +247,35 @@ describe('EditOperationTransformer', function () {
|
||||
expect(bPrime).to.be.an.instanceof(SetCommentStateOperation)
|
||||
expect(bPrime.toJSON()).to.deep.eql(b.toJSON())
|
||||
})
|
||||
|
||||
it('transformMultiple rebases two concurrent op lists so they converge', function () {
|
||||
const base = 'AB'
|
||||
// two sequential client edits, inserting at the start
|
||||
const as = [
|
||||
new TextOperation().insert('x').retain(2),
|
||||
new TextOperation().insert('y').retain(3),
|
||||
]
|
||||
// two sequential server edits, inserting at the end
|
||||
const bs = [
|
||||
new TextOperation().retain(2).insert('1'),
|
||||
new TextOperation().retain(3).insert('2'),
|
||||
]
|
||||
const asOrig = as.map(op => EditOperationBuilder.fromJSON(op.toJSON()))
|
||||
const bsOrig = bs.map(op => EditOperationBuilder.fromJSON(op.toJSON()))
|
||||
|
||||
EditOperationTransformer.transformMultiple(as, bs)
|
||||
|
||||
const applySeq = ops => {
|
||||
const file = new StringFileData(base)
|
||||
for (const op of ops) {
|
||||
file.edit(op)
|
||||
}
|
||||
return file.getContent()
|
||||
}
|
||||
// client edits then rebased server edits, and the mirror order, both converge
|
||||
expect(applySeq([...asOrig, ...bs])).to.equal('yxAB12')
|
||||
expect(applySeq([...bsOrig, ...as])).to.equal('yxAB12')
|
||||
})
|
||||
})
|
||||
|
||||
describe('EditOperationBuilder', function () {
|
||||
|
||||
Reference in New Issue
Block a user