mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-30 05:05:27 -05:00
76 lines
No EOL
2.9 KiB
CoffeeScript
76 lines
No EOL
2.9 KiB
CoffeeScript
RangesTracker = require "./RangesTracker"
|
|
logger = require "logger-sharelatex"
|
|
_ = require "lodash"
|
|
|
|
module.exports = RangesManager =
|
|
MAX_COMMENTS: 500
|
|
MAX_CHANGES: 2000
|
|
|
|
applyUpdate: (project_id, doc_id, entries = {}, updates = [], newDocLines, callback = (error, new_entries, ranges_were_collapsed) ->) ->
|
|
{changes, comments} = _.cloneDeep(entries)
|
|
rangesTracker = new RangesTracker(changes, comments)
|
|
emptyRangeCountBefore = RangesManager._emptyRangesCount(rangesTracker)
|
|
for update in updates
|
|
rangesTracker.track_changes = !!update.meta.tc
|
|
if !!update.meta.tc
|
|
rangesTracker.setIdSeed(update.meta.tc)
|
|
for op in update.op
|
|
try
|
|
rangesTracker.applyOp(op, { user_id: update.meta?.user_id })
|
|
catch error
|
|
return callback(error)
|
|
|
|
if rangesTracker.changes?.length > RangesManager.MAX_CHANGES or rangesTracker.comments?.length > RangesManager.MAX_COMMENTS
|
|
return callback new Error("too many comments or tracked changes")
|
|
|
|
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)
|
|
|
|
emptyRangeCountAfter = RangesManager._emptyRangesCount(rangesTracker)
|
|
rangesWereCollapsed = emptyRangeCountAfter > emptyRangeCountBefore
|
|
response = RangesManager._getRanges rangesTracker
|
|
logger.log {project_id, doc_id, changesCount: response.changes?.length, commentsCount: response.comments?.length, rangesWereCollapsed}, "applied updates to ranges"
|
|
callback null, response, rangesWereCollapsed
|
|
|
|
acceptChanges: (change_ids, ranges, callback = (error, ranges) ->) ->
|
|
{changes, comments} = ranges
|
|
logger.log "accepting #{ change_ids.length } changes in ranges"
|
|
rangesTracker = new RangesTracker(changes, comments)
|
|
rangesTracker.removeChangeIds(change_ids)
|
|
response = RangesManager._getRanges(rangesTracker)
|
|
callback null, response
|
|
|
|
deleteComment: (comment_id, ranges, callback = (error, ranges) ->) ->
|
|
{changes, comments} = ranges
|
|
logger.log {comment_id}, "deleting comment in ranges"
|
|
rangesTracker = new RangesTracker(changes, comments)
|
|
rangesTracker.removeCommentId(comment_id)
|
|
response = RangesManager._getRanges(rangesTracker)
|
|
callback null, response
|
|
|
|
_getRanges: (rangesTracker) ->
|
|
# 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
|
|
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 |