UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

84 lines (80 loc) 3.77 kB
import { deleteSelectedRange } from '@atlaskit/editor-common/selection'; import { stopPreservingSelection } from '../pm-plugins/selection-preservation/editor-commands'; var getKeyboardEventInfo = function getKeyboardEventInfo(event) { var key = event.key.toLowerCase(); var isMetaCtrl = event.metaKey || event.ctrlKey; var isDelete = ['backspace', 'delete'].includes(key); var isCut = isMetaCtrl && key === 'x'; var isPaste = isMetaCtrl && key === 'v'; var isUndo = isMetaCtrl && key === 'z' && !event.shiftKey; var isRedo = isMetaCtrl && (key === 'y' || key === 'z' && event.shiftKey); var isDestructive = isDelete || isCut || isPaste || isUndo || isRedo; var isModifierOnly = ['control', 'meta', 'alt', 'shift'].includes(key) && !isMetaCtrl; var isCopy = isMetaCtrl && key === 'c'; var isInert = isModifierOnly || isCopy; return { isDelete: isDelete, isDestructive: isDestructive, isInert: isInert }; }; /** * Handles key presses when a selection is being preserved, when the block menu is open or closed. * * Based on the key pressed and whether the block menu is open or closed: * 1. Handles key presses with custom logic (e.g. delete/backspace) * 2. Closes the block menu * 3. Stops preserving the selection * * This is used in two places: * 1. selection preservation plugin when selection is being preserved, and focus is in the editor. * 2. block menu UI component when focus is in the block menu. * * Ensures consistent behaviour for key presses in both scenarios. */ export var handleKeyDownWithPreservedSelection = function handleKeyDownWithPreservedSelection(api) { return function (event) { return function (_ref) { var _api$userIntent; var tr = _ref.tr; if (!api) { return tr; } var _getKeyboardEventInfo = getKeyboardEventInfo(event), isDelete = _getKeyboardEventInfo.isDelete, isDestructive = _getKeyboardEventInfo.isDestructive, isInert = _getKeyboardEventInfo.isInert; // Handle delete/backspace key presses with custom logic to ensure preserved selection is used if (isDelete) { var _api$blockControls; tr = deleteSelectedRange(tr, (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection); } var isBlockMenuOpen = ((_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || (_api$userIntent = _api$userIntent.sharedState.currentState()) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.currentUserIntent) === 'blockMenuOpen'; // When selected content is being removed/modified/undo/redo and the block menu is open // close the block menu and refocus the editor var shouldCloseBlockMenu = isDestructive && isBlockMenuOpen; if (shouldCloseBlockMenu) { var _api$blockControls2; (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || _api$blockControls2.commands.toggleBlockMenu({ closeMenu: true })({ tr: tr }); api.core.actions.focus({ scrollIntoView: false }); } // Stop preserving when: // 1. Content is being removed (delete/cut/paste) OR // 2. Menu is closed AND user pressed a non-inert key (i.e. action which modifies selection or content) // 3. undo/redo actions var shouldStopPreservingSelection = isDestructive || !isBlockMenuOpen && !isInert; if (shouldStopPreservingSelection) { stopPreservingSelection({ tr: tr }); } return tr; }; }; };