overleaf/services/document-updater/app/coffee/sharejs/helpers.coffee
2014-02-12 10:40:42 +00:00

65 lines
2.3 KiB
CoffeeScript

# These methods let you build a transform function from a transformComponent function
# for OT types like text and JSON in which operations are lists of components
# and transforming them requires N^2 work.
# Add transform and transformX functions for an OT type which has transformComponent defined.
# transformComponent(destination array, component, other component, side)
exports['_bt'] = bootstrapTransform = (type, transformComponent, checkValidOp, append) ->
transformComponentX = (left, right, destLeft, destRight) ->
transformComponent destLeft, left, right, 'left'
transformComponent destRight, right, left, 'right'
# Transforms rightOp by leftOp. Returns ['rightOp', clientOp']
type.transformX = type['transformX'] = transformX = (leftOp, rightOp) ->
checkValidOp leftOp
checkValidOp rightOp
newRightOp = []
for rightComponent in rightOp
# Generate newLeftOp by composing leftOp by rightComponent
newLeftOp = []
k = 0
while k < leftOp.length
nextC = []
transformComponentX leftOp[k], rightComponent, newLeftOp, nextC
k++
if nextC.length == 1
rightComponent = nextC[0]
else if nextC.length == 0
append newLeftOp, l for l in leftOp[k..]
rightComponent = null
break
else
# Recurse.
[l_, r_] = transformX leftOp[k..], nextC
append newLeftOp, l for l in l_
append newRightOp, r for r in r_
rightComponent = null
break
append newRightOp, rightComponent if rightComponent?
leftOp = newLeftOp
[leftOp, newRightOp]
# Transforms op with specified type ('left' or 'right') by otherOp.
type.transform = type['transform'] = (op, otherOp, type) ->
throw new Error "type must be 'left' or 'right'" unless type == 'left' or type == 'right'
return op if otherOp.length == 0
# TODO: Benchmark with and without this line. I _think_ it'll make a big difference...?
return transformComponent [], op[0], otherOp[0], type if op.length == 1 and otherOp.length == 1
if type == 'left'
[left, _] = transformX op, otherOp
left
else
[_, right] = transformX otherOp, op
right
if typeof WEB is 'undefined'
exports.bootstrapTransform = bootstrapTransform