| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- // @ts-check
- const _ = require('lodash')
- /**
- * @typedef {import('./types').CommentOp} CommentOp
- * @typedef {import('./types').DeleteOp} DeleteOp
- * @typedef {import('./types').InsertOp} InsertOp
- * @typedef {import('./types').Op} Op
- * @typedef {import('./types').TrackedChange} TrackedChange
- */
- /**
- * Returns true if the op is an insert
- *
- * @param {Op} op
- * @returns {op is InsertOp}
- */
- function isInsert(op) {
- return 'i' in op && op.i != null
- }
- /**
- * Returns true if the op is an insert
- *
- * @param {Op} op
- * @returns {op is DeleteOp}
- */
- function isDelete(op) {
- return 'd' in op && op.d != null
- }
- /**
- * Returns true if the op is a comment
- *
- * @param {Op} op
- * @returns {op is CommentOp}
- */
- function isComment(op) {
- return 'c' in op && op.c != null
- }
- /**
- * Get the length of a document from its lines
- *
- * @param {string[]} lines
- * @returns {number}
- */
- function getDocLength(lines) {
- let docLength = _.reduce(lines, (chars, line) => chars + line.length, 0)
- // Add newline characters. Lines are joined by newlines, but the last line
- // doesn't include a newline. We must make a special case for an empty list
- // so that it doesn't report a doc length of -1.
- docLength += Math.max(lines.length - 1, 0)
- return docLength
- }
- /**
- * Adds given tracked deletes to the given content.
- *
- * The history system includes tracked deletes in the document content.
- *
- * @param {string} content
- * @param {TrackedChange[]} trackedChanges
- * @return {string} content for the history service
- */
- function addTrackedDeletesToContent(content, trackedChanges) {
- let cursor = 0
- let result = ''
- for (const change of trackedChanges) {
- if (isDelete(change.op)) {
- // Add the content before the tracked delete
- result += content.slice(cursor, change.op.p)
- cursor = change.op.p
- // Add the content of the tracked delete
- result += change.op.d
- }
- }
- // Add the content after all tracked deletes
- result += content.slice(cursor)
- return result
- }
- /**
- * checks if the given originOrSource should be treated as a source or origin
- * TODO: remove this hack and remove all "source" references
- */
- function extractOriginOrSource(originOrSource) {
- let source = null
- let origin = null
- if (typeof originOrSource === 'string') {
- source = originOrSource
- } else if (originOrSource && typeof originOrSource === 'object') {
- origin = originOrSource
- }
- return { source, origin }
- }
- module.exports = {
- isInsert,
- isDelete,
- isComment,
- addTrackedDeletesToContent,
- getDocLength,
- extractOriginOrSource,
- }
|