all files / model/ DefaultChangeCompressor.js

3.85% Statements 1/26
0% Branches 0/14
0% Functions 0/2
3.85% Lines 1/26
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86                                                                                                                                                                         
/* eslint-disable no-unused-vars */
import { isEqual } from '../util'
import ObjectOperation from './ObjectOperation'
 
const MAXIMUM_CHANGE_DURATION = 1500
 
class DefaultChangeCompressor {
 
  shouldMerge(lastChange, newChange) {
    return false
    // var now = Date.now()
    // // var shouldMerge = (now - lastChange.timestamp < MAXIMUM_CHANGE_DURATION)
    // var shouldMerge = true
    // if (shouldMerge) {
    //   // we are only interested in compressing subsequent operations while typing
    //   // TODO: we could make our lifes easier by just tagging these changes
    //   var firstOp = lastChange.ops[0]
    //   var secondOp = newChange.ops[0]
    //   var firstDiff = firstOp.diff
    //   var secondDiff = secondOp.diff
    //   // HACK: this check is pretty optimistic. We should tag changes, so that
    //   // we can compress only changes related to typing here.
    //   shouldMerge = (
    //     firstOp.isUpdate('string') &&
    //     secondOp.isUpdate('string') &&
    //     secondDiff.getLength() === 1 &&
    //     firstDiff.type === secondDiff.type &&
    //     isEqual(firstOp.path, secondOp.path)
    //   )
    // }
 
    // return shouldMerge
  }
 
  /*
    This compresser tries to merge subsequent text operation
    to create more natural changes for persisting.
 
    @param {DocumentChange} first
    @param {DocumentChange} second
    @returns {boolean} `true` if the second could be merged into the first, `false` otherwise
  */
  merge(first, second) {
    // we are only interested in compressing subsequent operations while typing
    // TODO: we could make our lifes easier by just tagging these changes
    var firstOp = first.ops[0]
    var secondOp = second.ops[0]
    var firstDiff = firstOp.diff
    var secondDiff = secondOp.diff
    var mergedOp = false
    if (firstDiff.isInsert()) {
      if (firstDiff.pos+firstDiff.getLength() === secondDiff.pos) {
        mergedOp = firstOp.toJSON()
        mergedOp.diff.str += secondDiff.str
      }
    }
    else if (firstDiff.isDelete()) {
      // TODO: here is one case not covered
      // "012345": del(3, '3') del(3, '4') -> del(3, '34')
      if (firstDiff.pos === secondDiff.pos) {
        mergedOp = firstOp.toJSON()
        mergedOp.diff.str += secondDiff.str
      } else if (secondDiff.pos+secondDiff.getLength() === firstDiff.pos) {
        mergedOp = firstOp.toJSON()
        mergedOp.diff = secondDiff
        mergedOp.diff.str += firstDiff.str
      }
    }
    if (mergedOp) {
      first.ops[0] = ObjectOperation.fromJSON(mergedOp)
      if (first.ops.length > 1) {
        // just concatenating the other ops
        // TODO: we could compress the other ops as well, e.g., updates of annotation
        // ranges as they follow the same principle as the originating text operation.
        first.ops = first.ops.concat(second.ops.slice(1))
        first.after = second.after
      }
      return true
    }
    return false
  }
 
}
 
export default DefaultChangeCompressor