UNPKG

@wordpress/core-data

Version:
146 lines (145 loc) 5.29 kB
// packages/core-data/src/utils/crdt-user-selections.ts import { Y } from "@wordpress/sync"; import { CRDT_RECORD_MAP_KEY } from "../sync.mjs"; import { getRootMap } from "./crdt-utils.mjs"; var SelectionType = /* @__PURE__ */ ((SelectionType2) => { SelectionType2["None"] = "none"; SelectionType2["Cursor"] = "cursor"; SelectionType2["SelectionInOneBlock"] = "selection-in-one-block"; SelectionType2["SelectionInMultipleBlocks"] = "selection-in-multiple-blocks"; SelectionType2["WholeBlock"] = "whole-block"; return SelectionType2; })(SelectionType || {}); function getSelectionState(selectionStart, selectionEnd, yDoc) { const ymap = getRootMap(yDoc, CRDT_RECORD_MAP_KEY); const yBlocks = ymap.get("blocks") ?? new Y.Array(); const isSelectionEmpty = Object.keys(selectionStart).length === 0; const noSelection = { type: "none" /* None */ }; if (isSelectionEmpty) { return noSelection; } const isSelectionInOneBlock = selectionStart.clientId === selectionEnd.clientId; const isCursorOnly = isSelectionInOneBlock && selectionStart.offset === selectionEnd.offset; const isSelectionAWholeBlock = isSelectionInOneBlock && selectionStart.offset === void 0 && selectionEnd.offset === void 0; if (isSelectionAWholeBlock) { return { type: "whole-block" /* WholeBlock */, blockId: selectionStart.clientId }; } else if (isCursorOnly) { const cursorPosition = getCursorPosition(selectionStart, yBlocks); if (!cursorPosition) { return noSelection; } return { type: "cursor" /* Cursor */, blockId: selectionStart.clientId, cursorPosition }; } else if (isSelectionInOneBlock) { const cursorStartPosition2 = getCursorPosition( selectionStart, yBlocks ); const cursorEndPosition2 = getCursorPosition(selectionEnd, yBlocks); if (!cursorStartPosition2 || !cursorEndPosition2) { return noSelection; } return { type: "selection-in-one-block" /* SelectionInOneBlock */, blockId: selectionStart.clientId, cursorStartPosition: cursorStartPosition2, cursorEndPosition: cursorEndPosition2 }; } const cursorStartPosition = getCursorPosition(selectionStart, yBlocks); const cursorEndPosition = getCursorPosition(selectionEnd, yBlocks); if (!cursorStartPosition || !cursorEndPosition) { return noSelection; } return { type: "selection-in-multiple-blocks" /* SelectionInMultipleBlocks */, blockStartId: selectionStart.clientId, blockEndId: selectionEnd.clientId, cursorStartPosition, cursorEndPosition }; } function getCursorPosition(selection, blocks) { const block = findBlockByClientId(selection.clientId, blocks); if (!block || !selection.attributeKey || void 0 === selection.offset) { return null; } const attributes = block.get("attributes"); const currentYText = attributes?.get(selection.attributeKey); const relativePosition = Y.createRelativePositionFromTypeIndex( currentYText, selection.offset ); return { relativePosition, absoluteOffset: selection.offset }; } function findBlockByClientId(blockId, blocks) { for (const block of blocks) { if (block.get("clientId") === blockId) { return block; } const innerBlocks = block.get("innerBlocks"); if (innerBlocks && innerBlocks.length > 0) { const innerBlock = findBlockByClientId(blockId, innerBlocks); if (innerBlock) { return innerBlock; } } } return null; } function areSelectionsStatesEqual(selection1, selection2) { if (selection1.type !== selection2.type) { return false; } switch (selection1.type) { case "none" /* None */: return true; case "cursor" /* Cursor */: return selection1.blockId === selection2.blockId && areCursorPositionsEqual( selection1.cursorPosition, selection2.cursorPosition ); case "selection-in-one-block" /* SelectionInOneBlock */: return selection1.blockId === selection2.blockId && areCursorPositionsEqual( selection1.cursorStartPosition, selection2.cursorStartPosition ) && areCursorPositionsEqual( selection1.cursorEndPosition, selection2.cursorEndPosition ); case "selection-in-multiple-blocks" /* SelectionInMultipleBlocks */: return selection1.blockStartId === selection2.blockStartId && selection1.blockEndId === selection2.blockEndId && areCursorPositionsEqual( selection1.cursorStartPosition, selection2.cursorStartPosition ) && areCursorPositionsEqual( selection1.cursorEndPosition, selection2.cursorEndPosition ); case "whole-block" /* WholeBlock */: return selection1.blockId === selection2.blockId; default: return false; } } function areCursorPositionsEqual(cursorPosition1, cursorPosition2) { const isRelativePositionEqual = JSON.stringify(cursorPosition1.relativePosition) === JSON.stringify(cursorPosition2.relativePosition); const isAbsoluteOffsetEqual = cursorPosition1.absoluteOffset === cursorPosition2.absoluteOffset; return isRelativePositionEqual && isAbsoluteOffsetEqual; } export { SelectionType, areSelectionsStatesEqual, getSelectionState }; //# sourceMappingURL=crdt-user-selections.mjs.map