UNPKG

@wordpress/core-data

Version:
116 lines (115 loc) 3.63 kB
// packages/core-data/src/utils/crdt-selection.ts import { dispatch, select } from "@wordpress/data"; import { store as blockEditorStore } from "@wordpress/block-editor"; import { isUnmodifiedBlock } from "@wordpress/blocks"; import { Y } from "@wordpress/sync"; import { createBlockSelectionHistory, YSelectionType } from "./block-selection-history.mjs"; import { findBlockByClientIdInDoc } from "./crdt-utils.mjs"; var selectionHistoryMap = /* @__PURE__ */ new WeakMap(); function getBlockSelectionHistory(ydoc) { let history = selectionHistoryMap.get(ydoc); if (!history) { history = createBlockSelectionHistory(ydoc); selectionHistoryMap.set(ydoc, history); } return history; } function getSelectionHistory(ydoc) { return getBlockSelectionHistory(ydoc).getSelectionHistory(); } function updateSelectionHistory(ydoc, wpSelection) { return getBlockSelectionHistory(ydoc).updateSelection(wpSelection); } function convertYSelectionToBlockSelection(ySelection, ydoc) { if (ySelection.type === YSelectionType.RelativeSelection) { const { relativePosition, attributeKey, clientId } = ySelection; const absolutePosition = Y.createAbsolutePositionFromRelativePosition( relativePosition, ydoc ); if (absolutePosition) { return { clientId, attributeKey, offset: absolutePosition.index }; } } else if (ySelection.type === YSelectionType.BlockSelection) { return { clientId: ySelection.clientId, attributeKey: void 0, offset: void 0 }; } return null; } function findSelectionFromHistory(ydoc, selectionHistory) { for (const positionToTry of selectionHistory) { const { start, end } = positionToTry; const startBlock = findBlockByClientIdInDoc(start.clientId, ydoc); const endBlock = findBlockByClientIdInDoc(end.clientId, ydoc); if (!startBlock || !endBlock) { continue; } const startBlockSelection = convertYSelectionToBlockSelection( start, ydoc ); const endBlockSelection = convertYSelectionToBlockSelection( end, ydoc ); if (startBlockSelection === null || endBlockSelection === null) { continue; } return { selectionStart: startBlockSelection, selectionEnd: endBlockSelection }; } return null; } function restoreSelection(selectionHistory, ydoc) { const selectionToRestore = findSelectionFromHistory( ydoc, selectionHistory ); if (selectionToRestore === null) { return; } const { getBlock } = select(blockEditorStore); const { resetSelection } = dispatch(blockEditorStore); const { selectionStart, selectionEnd } = selectionToRestore; const isSelectionInSameBlock = selectionStart.clientId === selectionEnd.clientId; if (isSelectionInSameBlock) { const block = getBlock(selectionStart.clientId); const isBlockEmpty = block && isUnmodifiedBlock(block); const isBeginningOfEmptyBlock = 0 === selectionStart.offset && 0 === selectionEnd.offset && isBlockEmpty; if (isBeginningOfEmptyBlock) { const selectionStartWithoutOffset = { clientId: selectionStart.clientId }; const selectionEndWithoutOffset = { clientId: selectionEnd.clientId }; resetSelection( selectionStartWithoutOffset, selectionEndWithoutOffset, 0 ); } else { resetSelection(selectionStart, selectionEnd, 0); } } else { resetSelection(selectionEnd, selectionEnd, 0); } } export { getSelectionHistory, restoreSelection, updateSelectionHistory }; //# sourceMappingURL=crdt-selection.mjs.map