UNPKG

@atlaskit/editor-plugin-panel

Version:

Panel plugin for @atlaskit/editor-core.

83 lines (79 loc) 4.3 kB
import { isEmptyNode } from '@atlaskit/editor-common/utils'; import { keymap } from '@atlaskit/editor-prosemirror/keymap'; import { findParentNodeOfType, hasParentNodeOfType, setTextSelection } from '@atlaskit/editor-prosemirror/utils'; function findParentNode(selection, nodeType) { var parentPosition = findParentNodeOfType(nodeType)(selection); if (parentPosition) { return parentPosition.node; } return null; } function isInsideAnEmptyNode(selection, nodeType, schema) { var parentNode = findParentNode(selection, nodeType); return parentNode && isEmptyNode(schema)(parentNode); } // Somewhat broken and subverted: https://product-fabric.atlassian.net/browse/ED-6504 export function keymapPlugin() { var deleteCurrentItem = function deleteCurrentItem($from, tr) { return tr.delete($from.before($from.depth) - 1, $from.end($from.depth) + 1); }; var keymaps = { Backspace: function Backspace(state, dispatch) { var _$previousPos$nodeAft, _nodeBeforePanel$type; var selection = state.selection, nodes = state.schema.nodes, tr = state.tr; var panel = nodes.panel, blockquote = nodes.blockquote, orderedList = nodes.orderedList, bulletList = nodes.bulletList, mediaSingle = nodes.mediaSingle, mediaGroup = nodes.mediaGroup, extension = nodes.extension; var $from = selection.$from, $to = selection.$to; // Don't do anything if selection is a range if ($from.pos !== $to.pos) { return false; } // If not at the start of a panel, no joining will happen so allow default behaviour (backspacing characters etc..) if ($from.parentOffset !== 0) { return false; } var $previousPos = tr.doc.resolve(Math.max(0, $from.before($from.depth) - 1)); var previousNodeType = $previousPos.pos > 0 && $previousPos.parent && $previousPos.parent.type; var parentNodeType = $from.parent.type; var isPreviousNodeAPanel = previousNodeType === panel; var isParentNodeAPanel = parentNodeType === panel; var nodeBeforePanel = $previousPos === null || $previousPos === void 0 ? void 0 : $previousPos.nodeBefore; var isPreviousNodeMedia = previousNodeType === mediaSingle || previousNodeType === mediaGroup; var isPreviousNodeAList = previousNodeType === bulletList || previousNodeType === orderedList; // identifies if new position after backspace is at the start of a non-bodied extension node var isPreviousPosAtExtension = ((_$previousPos$nodeAft = $previousPos.nodeAfter) === null || _$previousPos$nodeAft === void 0 ? void 0 : _$previousPos$nodeAft.type) === extension; // Stops merging panels when deleting empty paragraph in between // Stops merging blockquotes with panels when deleting from start of blockquote if (isPreviousNodeAPanel && !isParentNodeAPanel && !isPreviousPosAtExtension || isInsideAnEmptyNode(selection, panel, state.schema) || hasParentNodeOfType(blockquote)(selection) && !isPreviousNodeAList && !isPreviousNodeMedia && !isPreviousPosAtExtension || // Lift line of panel content up and out of the panel, when backspacing // at the start of a panel, if the node before the panel is an 'isolating' node // (for e.g. a table, or an expand), otherwise the default prosemirror backspace // behaviour will fallback to 'select node backward' logic because the node // before is an isolating node. nodeBeforePanel !== null && nodeBeforePanel !== void 0 && (_nodeBeforePanel$type = nodeBeforePanel.type) !== null && _nodeBeforePanel$type !== void 0 && (_nodeBeforePanel$type = _nodeBeforePanel$type.spec) !== null && _nodeBeforePanel$type !== void 0 && _nodeBeforePanel$type.isolating && hasParentNodeOfType(panel)(selection)) { var content = $from.node($from.depth).content; var insertPos = $previousPos.pos; deleteCurrentItem($from, tr).insert(insertPos, content); if (dispatch) { dispatch(setTextSelection(insertPos)(tr).scrollIntoView()); } return true; } var nodeType = $from.node().type; if (nodeType !== panel) { return false; } return true; } }; return keymap(keymaps); } export default keymapPlugin;