Skip to content

Instantly share code, notes, and snippets.

@josephg
Last active January 8, 2019 01:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josephg/cc0a125a2d6a7637dabc79a865a7483c to your computer and use it in GitHub Desktop.
Save josephg/cc0a125a2d6a7637dabc79a865a7483c to your computer and use it in GitHub Desktop.
transform raw string positions with text ops
const {strPosToUni, uniToStrPos} = require('unicount')
// The cursor position (input and output) are specified in JS string
// offsets here.
function transformJSPosition(cursor /*: number*/, doc /*: string*/, op /*: TextOp*/) {
let prePos = 0, postPos = 0 // string index in doc.
for (let i = 0; i < op.length && cursor > postPos; i++) {
const c = op[i]
// I could actually use the op_iter stuff above - but I think its simpler
// like this.
switch (typeof c) {
case 'number': { // skip
const offset = uniToStrPos(doc.slice(prePos), c)
prePos += offset
postPos += offset
break
}
case 'string': // insert
// Its safe to use c.length here because they're both utf16 offsets.
// Ignoring pos because the doc doesn't know about the insert yet.
postPos += c.length
cursor += c.length
break
case 'object': // delete
cursor -= Math.min(uniToStrPos(doc.slice(prePos), c.d), cursor - postPos)
prePos += c.d
break
}
}
return cursor
}
const {type} = require('ot-text-unicode')
let doc = '...'
let cursors = [{user: 'jane', pos: 5}, {user: 'fred', pos: 100}]
function onRemoteOp(op) {
for (let user of cursors) {
// Update user positions based on operation. doc must be the document as a
// string *before* the operation has been applied!
transformJSPosition(user.pos, op)
}
doc = type.apply(doc, op)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment