mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 06:03:45 +01:00
Standardise types for ranges (#16927)
GitOrigin-RevId: 28dd0eb67e1684e6bd0e452d15315ce1f9e3481a
This commit is contained in:
+31
-34
@@ -8,9 +8,12 @@ import {
|
||||
} from '../vertical-overflow'
|
||||
import { EditorSelection, EditorState } from '@codemirror/state'
|
||||
import { EditorView, ViewUpdate } from '@codemirror/view'
|
||||
import { CurrentDoc } from '../../../../../../types/current-doc'
|
||||
import { fullHeightCoordsAtPos } from '../../utils/layer'
|
||||
import { debounce } from 'lodash'
|
||||
import { Change, EditOperation } from '../../../../../../types/change'
|
||||
import { ThreadId } from '../../../../../../types/review-panel/review-panel'
|
||||
import { isDeleteOperation, isInsertOperation } from '@/utils/operations'
|
||||
import { DocumentContainer } from '@/features/ide-react/editor/document-container'
|
||||
|
||||
// With less than this number of entries, don't bother culling to avoid
|
||||
// little UI jumps when scrolling.
|
||||
@@ -75,7 +78,7 @@ export type UpdateType =
|
||||
|
||||
export const createChangeManager = (
|
||||
view: EditorView,
|
||||
currentDoc: CurrentDoc
|
||||
currentDoc: DocumentContainer
|
||||
): ChangeManager => {
|
||||
/**
|
||||
* Calculate the screen coordinates of each entry (change or comment),
|
||||
@@ -152,7 +155,7 @@ export const createChangeManager = (
|
||||
/**
|
||||
* Add a comment (thread) to the ShareJS doc when it's created
|
||||
*/
|
||||
const addComment = (offset: number, length: number, threadId: string) => {
|
||||
const addComment = (offset: number, length: number, threadId: ThreadId) => {
|
||||
currentDoc.submitOp({
|
||||
c: view.state.doc.sliceString(offset, offset + length),
|
||||
p: offset,
|
||||
@@ -164,14 +167,14 @@ export const createChangeManager = (
|
||||
* Remove a comment (thread) from the range tracker when it's deleted
|
||||
*/
|
||||
const removeComment = (commentId: string) => {
|
||||
currentDoc.ranges.removeCommentId(commentId)
|
||||
currentDoc.ranges!.removeCommentId(commentId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove tracked changes from the range tracker when they're accepted
|
||||
*/
|
||||
const acceptChanges = (changeIds: string[]) => {
|
||||
currentDoc.ranges.removeChangeIds(changeIds)
|
||||
currentDoc.ranges!.removeChangeIds(changeIds)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,7 +182,9 @@ export const createChangeManager = (
|
||||
* and restore the original content
|
||||
*/
|
||||
const rejectChanges = (changeIds: string[]) => {
|
||||
const changes: any[] = currentDoc.ranges.getChanges(changeIds)
|
||||
const changes = currentDoc.ranges!.getChanges(
|
||||
changeIds
|
||||
) as Change<EditOperation>[]
|
||||
|
||||
if (changes.length === 0) {
|
||||
return {}
|
||||
@@ -242,38 +247,30 @@ export const createChangeManager = (
|
||||
const changesToDispatch = changes.map(change => {
|
||||
const { op } = change
|
||||
|
||||
const opType = 'i' in op ? 'i' : 'c' in op ? 'c' : 'd'
|
||||
if (isInsertOperation(op)) {
|
||||
const from = op.p
|
||||
const content = op.i
|
||||
const to = from + content.length
|
||||
|
||||
switch (opType) {
|
||||
case 'd': {
|
||||
return {
|
||||
from: op.p,
|
||||
to: op.p,
|
||||
insert: op.d,
|
||||
}
|
||||
const text = view.state.doc.sliceString(from, to)
|
||||
|
||||
if (text !== content) {
|
||||
throw new Error(
|
||||
`Op to be removed (${JSON.stringify(
|
||||
change.op
|
||||
)}) does not match editor text '${text}'`
|
||||
)
|
||||
}
|
||||
|
||||
case 'i': {
|
||||
const from = op.p
|
||||
const content = op.i
|
||||
const to = from + content.length
|
||||
|
||||
const text = view.state.doc.sliceString(from, to)
|
||||
|
||||
if (text !== content) {
|
||||
throw new Error(
|
||||
`Op to be removed (${JSON.stringify(
|
||||
change.op
|
||||
)}) does not match editor text '${text}'`
|
||||
)
|
||||
}
|
||||
|
||||
return { from, to, insert: '' }
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new Error(`unknown change: ${JSON.stringify(change)}`)
|
||||
return { from, to, insert: '' }
|
||||
} else if (isDeleteOperation(op)) {
|
||||
return {
|
||||
from: op.p,
|
||||
to: op.p,
|
||||
insert: op.d,
|
||||
}
|
||||
} else {
|
||||
throw new Error(`unknown change type: ${JSON.stringify(change)}`)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Range, RangeSet, RangeValue, Transaction } from '@codemirror/state'
|
||||
import { CurrentDoc } from '../../../../../../types/current-doc'
|
||||
import {
|
||||
AnyOperation,
|
||||
Change,
|
||||
ChangeOperation,
|
||||
CommentOperation,
|
||||
} from '../../../../../../types/change'
|
||||
import { ThreadId } from '../../../../../../types/review-panel/review-panel'
|
||||
import { DocumentContainer } from '@/features/ide-react/editor/document-container'
|
||||
|
||||
export type StoredComment = {
|
||||
text: string
|
||||
@@ -20,14 +20,14 @@ export type StoredComment = {
|
||||
* Find tracked comments within the range of the current transaction's changes
|
||||
*/
|
||||
export const findCommentsInCut = (
|
||||
currentDoc: CurrentDoc,
|
||||
currentDoc: DocumentContainer,
|
||||
transaction: Transaction
|
||||
) => {
|
||||
const items: StoredComment[] = []
|
||||
|
||||
transaction.changes.iterChanges((fromA, toA) => {
|
||||
const comments = currentDoc.ranges.comments
|
||||
.filter(
|
||||
const comments = currentDoc
|
||||
.ranges!.comments.filter(
|
||||
comment =>
|
||||
fromA <= comment.op.p && comment.op.p + comment.op.c.length <= toA
|
||||
)
|
||||
@@ -55,7 +55,7 @@ export const findCommentsInPaste = (
|
||||
storedComments: StoredComment[],
|
||||
transaction: Transaction
|
||||
) => {
|
||||
const ops: ChangeOperation[] = []
|
||||
const ops: CommentOperation[] = []
|
||||
|
||||
transaction.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
|
||||
const insertedText = inserted.toString()
|
||||
@@ -71,7 +71,7 @@ export const findCommentsInPaste = (
|
||||
ops.push({
|
||||
c: text,
|
||||
p: fromB + offset,
|
||||
t: comment.id,
|
||||
t: comment.id as ThreadId,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -93,13 +93,13 @@ class CommentRangeValue extends RangeValue {
|
||||
* Find tracked comments with no content with the ranges of a transaction's changes
|
||||
*/
|
||||
export const findDetachedCommentsInChanges = (
|
||||
currentDoc: CurrentDoc,
|
||||
currentDoc: DocumentContainer,
|
||||
transaction: Transaction
|
||||
) => {
|
||||
const items: Range<CommentRangeValue>[] = []
|
||||
|
||||
transaction.changes.iterChanges((fromA, toA) => {
|
||||
for (const comment of currentDoc.ranges.comments) {
|
||||
for (const comment of currentDoc.ranges!.comments) {
|
||||
const content = comment.op.c
|
||||
|
||||
// TODO: handle comments that were never attached
|
||||
@@ -124,7 +124,7 @@ export const findDetachedCommentsInChanges = (
|
||||
* (used when restoring comments on paste)
|
||||
*/
|
||||
const submitOps = (
|
||||
currentDoc: CurrentDoc,
|
||||
currentDoc: DocumentContainer,
|
||||
ops: AnyOperation[],
|
||||
transaction: Transaction
|
||||
) => {
|
||||
@@ -133,14 +133,14 @@ const submitOps = (
|
||||
}
|
||||
|
||||
// Check that comments still match text. Will throw error if not.
|
||||
currentDoc.ranges.validate(transaction.state.doc.toString())
|
||||
currentDoc.ranges!.validate(transaction.state.doc.toString())
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the ShareJS doc to fire an event, then submit the operations.
|
||||
*/
|
||||
const submitOpsAfterEvent = (
|
||||
currentDoc: CurrentDoc,
|
||||
currentDoc: DocumentContainer,
|
||||
eventName: string,
|
||||
ops: AnyOperation[],
|
||||
transaction: Transaction
|
||||
@@ -161,7 +161,7 @@ const submitOpsAfterEvent = (
|
||||
* Look through the comments stored on cut, and restore those in text that matches the pasted text.
|
||||
*/
|
||||
export const restoreCommentsOnPaste = (
|
||||
currentDoc: CurrentDoc,
|
||||
currentDoc: DocumentContainer,
|
||||
transaction: Transaction,
|
||||
storedComments: StoredComment[]
|
||||
) => {
|
||||
@@ -183,18 +183,18 @@ export const restoreCommentsOnPaste = (
|
||||
* When undoing a change, find comments from the original content and restore them.
|
||||
*/
|
||||
export const restoreDetachedComments = (
|
||||
currentDoc: CurrentDoc,
|
||||
currentDoc: DocumentContainer,
|
||||
transaction: Transaction,
|
||||
storedComments: RangeSet<any>
|
||||
) => {
|
||||
const ops: ChangeOperation[] = []
|
||||
const ops: CommentOperation[] = []
|
||||
|
||||
const cursor = storedComments.iter()
|
||||
|
||||
while (cursor.value) {
|
||||
const { id } = cursor.value.comment
|
||||
|
||||
const comment = currentDoc.ranges.comments.find(item => item.id === id)
|
||||
const comment = currentDoc.ranges!.comments.find(item => item.id === id)
|
||||
|
||||
// check that the comment still exists and is detached
|
||||
if (comment && comment.op.c === '') {
|
||||
|
||||
Reference in New Issue
Block a user