2016-12-08 07:31:43 -05:00
RangesTracker = require "./RangesTracker"
logger = require "logger-sharelatex"
2019-04-11 08:25:03 -04:00
_ = require "lodash"
2016-12-08 07:31:43 -05:00
module . exports = RangesManager =
2017-01-10 10:58:11 -05:00
MAX _COMMENTS : 500
2017-02-24 08:58:42 -05:00
MAX _CHANGES : 2000
2017-01-10 10:58:11 -05:00
2019-04-11 08:25:03 -04:00
applyUpdate : ( project _id , doc _id , entries = { } , updates = [ ] , newDocLines , callback = ( error , new _entries , ranges _were _collapsed ) - > ) - >
{ changes , comments } = _ . cloneDeep ( entries )
2016-12-08 07:31:43 -05:00
rangesTracker = new RangesTracker ( changes , comments )
2019-04-11 08:25:03 -04:00
emptyRangeCountBefore = RangesManager . _emptyRangesCount ( rangesTracker )
2016-12-08 07:31:43 -05:00
for update in updates
rangesTracker . track _changes = ! ! update . meta . tc
2017-01-09 04:46:58 -05:00
if ! ! update . meta . tc
rangesTracker . setIdSeed ( update . meta . tc )
2016-12-08 07:31:43 -05:00
for op in update . op
2017-03-06 14:05:11 -05:00
try
rangesTracker . applyOp ( op , { user _id : update . meta ? . user _id } )
catch error
return callback ( error )
2017-01-10 10:58:11 -05:00
if rangesTracker . changes ? . length > RangesManager . MAX _CHANGES or rangesTracker . comments ? . length > RangesManager . MAX _COMMENTS
return callback new Error ( "too many comments or tracked changes" )
2017-01-09 08:41:18 -05:00
2017-03-15 10:12:06 -04:00
try
# This is a consistency check that all of our ranges and
# comments still match the corresponding text
rangesTracker . validate ( newDocLines . join ( "\n" ) )
catch error
logger . error { err : error , project _id , doc _id , newDocLines , updates } , "error validating ranges"
return callback ( error )
2019-04-11 08:25:03 -04:00
emptyRangeCountAfter = RangesManager . _emptyRangesCount ( rangesTracker )
rangesWereCollapsed = emptyRangeCountAfter > emptyRangeCountBefore
2017-01-09 08:41:18 -05:00
response = RangesManager . _getRanges rangesTracker
2019-04-11 08:25:03 -04:00
logger . log { project _id , doc _id , changesCount : response . changes ? . length , commentsCount : response . comments ? . length , rangesWereCollapsed } , "applied updates to ranges"
callback null , response , rangesWereCollapsed
2017-01-09 08:41:18 -05:00
2017-05-05 10:12:06 -04:00
acceptChanges : ( change _ids , ranges , callback = ( error , ranges ) - > ) - >
2017-05-04 10:32:54 -04:00
{ changes , comments } = ranges
2017-05-08 11:34:17 -04:00
logger . log "accepting #{ change_ids.length } changes in ranges"
2017-05-04 10:32:54 -04:00
rangesTracker = new RangesTracker ( changes , comments )
2017-05-08 11:08:42 -04:00
rangesTracker . removeChangeIds ( change _ids )
2017-05-04 10:32:54 -04:00
response = RangesManager . _getRanges ( rangesTracker )
callback null , response
2017-01-24 09:57:11 -05:00
deleteComment : ( comment _id , ranges , callback = ( error , ranges ) - > ) - >
{ changes , comments } = ranges
2017-02-23 07:57:47 -05:00
logger . log { comment _id } , "deleting comment in ranges"
2017-01-24 09:57:11 -05:00
rangesTracker = new RangesTracker ( changes , comments )
rangesTracker . removeCommentId ( comment _id )
response = RangesManager . _getRanges ( rangesTracker )
callback null , response
2017-01-09 08:41:18 -05:00
_getRanges : ( rangesTracker ) - >
2016-12-08 07:31:43 -05:00
# Return the minimal data structure needed , since most documents won ' t have any
# changes or comments
response = { }
if rangesTracker . changes ? . length > 0
response ? = { }
response . changes = rangesTracker . changes
if rangesTracker . comments ? . length > 0
response ? = { }
response . comments = rangesTracker . comments
2019-04-11 08:25:03 -04:00
return response
_emptyRangesCount : ( ranges ) - >
count = 0
for comment in ( ranges . comments or [ ] )
if comment . op . c == ""
count ++
for change in ( ranges . changes or [ ] ) when change . op . i ?
if change . op . i == ""
count ++
return count