UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

76 lines 2.72 kB
import { Fragment } from '@atlaskit/editor-prosemirror/model'; /** * Narrows a full-list replacement to the minimal changed range. * * Compares the old root list node with the new replacement fragment * from both ends to find the first and last positions where they differ, * then returns only the changed subrange. * * This reduces the scope of `tr.replaceWith()` so that remote cursors * on unchanged items are preserved during collaborative editing. */ export function narrowReplacementRange(doc, rootListStart, rootListEnd, fragment, contentStartOffsets) { var oldNode = doc.nodeAt(rootListStart); var newNode = fragment.childCount === 1 ? fragment.firstChild : null; if (!oldNode || !newNode || newNode.type !== oldNode.type) { return { start: rootListStart, end: rootListEnd, fragment: fragment, adjustedContentStartOffsets: contentStartOffsets }; } var minChildCount = Math.min(oldNode.childCount, newNode.childCount); var commonPrefixChildren = 0; var prefixSize = 0; for (var i = 0; i < minChildCount; i++) { var oldChild = oldNode.child(i); var newChild = newNode.child(i); if (oldChild.eq(newChild)) { commonPrefixChildren++; prefixSize += oldChild.nodeSize; } else { break; } } var commonSuffixChildren = 0; var suffixSize = 0; for (var _i = 0; _i < minChildCount - commonPrefixChildren; _i++) { var _oldChild = oldNode.child(oldNode.childCount - 1 - _i); var _newChild = newNode.child(newNode.childCount - 1 - _i); if (_oldChild.eq(_newChild)) { commonSuffixChildren++; suffixSize += _oldChild.nodeSize; } else { break; } } var totalCommon = commonPrefixChildren + commonSuffixChildren; if (totalCommon >= oldNode.childCount && totalCommon >= newNode.childCount) { return { start: rootListStart, end: rootListStart, fragment: Fragment.empty, adjustedContentStartOffsets: contentStartOffsets }; } var narrowedStart = rootListStart + 1 + prefixSize; var narrowedEnd = rootListEnd - 1 - suffixSize; var changedChildStart = commonPrefixChildren; var changedChildEnd = newNode.childCount - commonSuffixChildren; var changedNodes = []; for (var _i2 = changedChildStart; _i2 < changedChildEnd; _i2++) { changedNodes.push(newNode.child(_i2)); } var narrowedFragment = Fragment.from(changedNodes); var prefixOffset = 1 + prefixSize; var adjustedContentStartOffsets = contentStartOffsets.map(function (offset) { return offset - prefixOffset; }); return { start: narrowedStart, end: narrowedEnd, fragment: narrowedFragment, adjustedContentStartOffsets: adjustedContentStartOffsets }; }