UNPKG

@atlaskit/editor-plugin-selection

Version:

Selection plugin for @atlaskit/editor-core

66 lines (60 loc) 2.83 kB
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin'; import { TextSelection } from '@atlaskit/editor-prosemirror/state'; import { autoExpandSelectionRangeOnInlineNodePluginKey } from './auto-expand-selection-range-on-inline-node-key'; export const createAutoExpandSelectionRangeOnInlineNodePlugin = () => { let mouseDownElement = null; return new SafePlugin({ key: autoExpandSelectionRangeOnInlineNodePluginKey, props: { handleDOMEvents: { mousedown: (_view, event) => { // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting mouseDownElement = event.target; }, mouseup: (view, event) => { // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting const mouseUpElement = event.target; // terminate early if mouse down and mouse up elements are the same -> e.g a click event // or mouse down doesn't trigger if (!mouseDownElement || mouseDownElement === mouseUpElement) { mouseDownElement = null; return; } // reset mouse down element after mouse up event // so that we can detect the next mouse down event is triggered right after mouse up event or not mouseDownElement = null; // terminate early if mouse up event is not fired on inline node if (!isMouseUpOnSupportedNode(mouseUpElement)) { return; } const { dispatch, state } = view; const { selection } = state; // terminate early if current selection is not a text selection -> e.g. table cell selection if (!(selection instanceof TextSelection)) { return; } // find the document position of the mouse up element const elementStartPosition = view.posAtDOM(mouseUpElement, 0); // find out the direction of selection const isAnchorBeforeElement = selection.$anchor.pos <= elementStartPosition; const expandedSelectionHeadPosition = isAnchorBeforeElement ? elementStartPosition + 1 : elementStartPosition; // expand the selection to include the mouse up element const tr = state.tr.setSelection(TextSelection.create(state.doc, selection.$anchor.pos, expandedSelectionHeadPosition)); dispatch(tr); } } } }); }; const isMouseUpOnSupportedNode = mouseUpElement => { const supportedNodes = ['emoji', 'status', 'date', 'mention', 'inlineCard']; const supportedNodeViewContentClassNamesList = supportedNodes.map(nodeType => `.${nodeType}View-content-wrap`).join(', '); return !!mouseUpElement.closest(supportedNodeViewContentClassNamesList); };