Merge pull request #20052 from overleaf/em-tracked-deletes-limit

Include tracked deletes when limiting document size

GitOrigin-RevId: 9d7b2870001fb942eaa92db78993fee1ddb3937c
This commit is contained in:
Eric Mc Sween 2024-08-26 07:50:34 -04:00 committed by Copybot
parent e643a8ea32
commit 8b4b454b97
7 changed files with 40 additions and 14 deletions

View file

@ -768,6 +768,16 @@ class RangesTracker {
return this._dirtyState return this._dirtyState
} }
getTrackedDeletesLength() {
let length = 0
for (const change of this.changes) {
if (change.op.d != null) {
length += change.op.d.length
}
}
return length
}
_markAsDirty(object, type, action) { _markAsDirty(object, type, action) {
this._dirtyState[type][action][object.id] = object this._dirtyState[type][action][object.id] = object
} }

View file

@ -326,6 +326,7 @@
"do_you_want_to_overwrite_them": "", "do_you_want_to_overwrite_them": "",
"document_too_long": "", "document_too_long": "",
"document_too_long_detail": "", "document_too_long_detail": "",
"document_too_long_tracked_deletes": "",
"document_updated_externally": "", "document_updated_externally": "",
"document_updated_externally_detail": "", "document_updated_externally_detail": "",
"documentation": "", "documentation": "",

View file

@ -548,10 +548,14 @@ export const EditorManagerProvider: FC = ({ children }) => {
if (message.includes('maxDocLength')) { if (message.includes('maxDocLength')) {
openDoc(doc, { forceReopen: true }) openDoc(doc, { forceReopen: true })
showGenericMessageModal( const hasTrackedDeletes =
t('document_too_long'), document.ranges != null &&
t('document_too_long_detail') document.ranges.changes.some(change => 'd' in change.op)
) const explanation = hasTrackedDeletes
? `${t('document_too_long_detail')} ${t('document_too_long_tracked_deletes')}`
: t('document_too_long_detail')
showGenericMessageModal(t('document_too_long'), explanation)
setDocTooLongErrorShown(true) setDocTooLongErrorShown(true)
} else if (/too many comments or tracked changes/.test(message)) { } else if (/too many comments or tracked changes/.test(message)) {
showGenericMessageModal( showGenericMessageModal(

View file

@ -127,9 +127,7 @@ export class DocumentContainer extends EventEmitter {
if (this.doc) { if (this.doc) {
this.doc.attachToCM6(this.cm6) this.doc.attachToCM6(this.cm6)
} }
if (this.cm6) { this.cm6.on('change', this.checkConsistency)
this.cm6.on('change', this.checkConsistency)
}
} }
detachFromCM6() { detachFromCM6() {

View file

@ -1,6 +1,7 @@
import { Prec, Transaction, Annotation, ChangeSpec } from '@codemirror/state' import { Prec, Transaction, Annotation, ChangeSpec } from '@codemirror/state'
import { EditorView, ViewPlugin } from '@codemirror/view' import { EditorView, ViewPlugin } from '@codemirror/view'
import { EventEmitter } from 'events' import { EventEmitter } from 'events'
import RangesTracker from '@overleaf/ranges-tracker'
import { ShareDoc } from '../../../../../types/share-doc' import { ShareDoc } from '../../../../../types/share-doc'
import { debugConsole } from '@/utils/debugging' import { debugConsole } from '@/utils/debugging'
import { DocumentContainer } from '@/features/ide-react/editor/document-container' import { DocumentContainer } from '@/features/ide-react/editor/document-container'
@ -45,7 +46,7 @@ export const realtime = (
return { return {
update(update) { update(update) {
if (update.docChanged) { if (update.docChanged) {
editor.handleUpdateFromCM(update.transactions) editor.handleUpdateFromCM(update.transactions, currentDoc.ranges)
} }
}, },
destroy() { destroy() {
@ -166,8 +167,13 @@ export class EditorFacade extends EventEmitter {
// Process an update from CodeMirror, applying changes to the // Process an update from CodeMirror, applying changes to the
// ShareJs doc if appropriate // ShareJs doc if appropriate
handleUpdateFromCM(transactions: readonly Transaction[]) { handleUpdateFromCM(
transactions: readonly Transaction[],
ranges?: RangesTracker
) {
const shareDoc = this.shareDoc const shareDoc = this.shareDoc
const trackedDeletesLength =
ranges != null ? ranges.getTrackedDeletesLength() : 0
if (!shareDoc) { if (!shareDoc) {
throw new Error('Trying to process updates with no shareDoc') throw new Error('Trying to process updates with no shareDoc')
@ -181,10 +187,15 @@ export class EditorFacade extends EventEmitter {
return return
} }
if ( // This is an approximation. Some deletes could have generated new
this.maxDocLength && // tracked deletes since we measured trackedDeletesLength at the top of
transaction.changes.desc.newLength >= this.maxDocLength // the function. Unfortunately, the ranges tracker is only updated
) { // after all transactions are processed, so it's not easy to get an
// exact number.
const fullDocLength =
transaction.changes.desc.newLength + trackedDeletesLength
if (this.maxDocLength && fullDocLength >= this.maxDocLength) {
shareDoc.emit( shareDoc.emit(
'error', 'error',
new Error('document length is greater than maxDocLength') new Error('document length is greater than maxDocLength')

View file

@ -461,7 +461,8 @@
"do_you_want_to_overwrite_it_plural": "Do you want to overwrite them?", "do_you_want_to_overwrite_it_plural": "Do you want to overwrite them?",
"do_you_want_to_overwrite_them": "Do you want to overwrite them?", "do_you_want_to_overwrite_them": "Do you want to overwrite them?",
"document_too_long": "Document Too Long", "document_too_long": "Document Too Long",
"document_too_long_detail": "Sorry, this file is too long to be edited manually. Please upload it directly.", "document_too_long_detail": "Sorry, this file is too long to be edited manually. Please try to split it into smaller files.",
"document_too_long_tracked_deletes": "You can also accept pending deletions to reduce the size of the file.",
"document_updated_externally": "Document Updated Externally", "document_updated_externally": "Document Updated Externally",
"document_updated_externally_detail": "This document was just updated externally. Any recent changes you have made may have been overwritten. To see previous versions, please look in the history.", "document_updated_externally_detail": "This document was just updated externally. Any recent changes you have made may have been overwritten. To see previous versions, please look in the history.",
"documentation": "Documentation", "documentation": "Documentation",

View file

@ -78,6 +78,7 @@ export const mockDoc = (content = defaultContent) => {
comments: [], comments: [],
getIdSeed: () => '123', getIdSeed: () => '123',
setIdSeed: () => {}, setIdSeed: () => {},
getTrackedDeletesLength: () => 0,
}, },
setTrackChangesIdSeeds: () => {}, setTrackChangesIdSeeds: () => {},
getTrackingChanges: () => true, getTrackingChanges: () => true,