@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
59 lines (58 loc) • 2.03 kB
JavaScript
import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
import { GapCursorSelection } from '../selection';
/**
* Compute the new selection offsets after list items have been moved/indented/outdented.
*
* Uses the content start offsets computed during fragment rebuild to map each
* selection endpoint to its new absolute position, accounting for the change
* in the list structure.
*/
export function computeSelectionOffsets({
items,
startIndex,
endIndex,
originalFrom,
originalTo,
contentStartOffsets,
rootListStart,
docSize
}) {
// +1 shifts from the outer edge of the list item node to the start of the content within
const fromContentStart = items[startIndex].pos + 1;
const toContentStart = items[endIndex].pos + 1;
const fromOffset = originalFrom - fromContentStart;
const toOffset = originalTo - toContentStart;
const clamp = pos => Math.min(Math.max(0, pos), docSize);
return {
from: clamp(rootListStart + contentStartOffsets[startIndex] + fromOffset),
to: clamp(rootListStart + contentStartOffsets[endIndex] + toOffset)
};
}
/**
* Restore the transaction's selection after a list structural change
* (indent/outdent of list items or task list items).
*
* Uses the content start offsets computed during fragment rebuild to
* map each selection endpoint to its new absolute position.
*
* Handles NodeSelection, GapCursorSelection, and TextSelection.
*/
export function restoreSelection({
tr,
originalSelection,
from,
to
}) {
const maxPos = tr.doc.content.size;
if (originalSelection instanceof NodeSelection) {
try {
tr.setSelection(NodeSelection.create(tr.doc, Math.min(from, maxPos - 1)));
} catch {
tr.setSelection(Selection.near(tr.doc.resolve(from)));
}
} else if (originalSelection instanceof GapCursorSelection) {
tr.setSelection(new GapCursorSelection(tr.doc.resolve(from), originalSelection.side));
} else {
tr.setSelection(TextSelection.create(tr.doc, from, to));
}
}