UNPKG

@atlaskit/editor-plugin-text-formatting

Version:

Text-formatting plugin for @atlaskit/editor-core

59 lines (56 loc) 2.96 kB
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin'; import { TextSelection } from '@atlaskit/editor-prosemirror/state'; // eslint-disable-next-line import/no-anonymous-default-export const _default_1 = new SafePlugin({ props: { handleClick(view, clickPos, event) { // Don't apply in Edge as per ED-4546 // Ignored via go/ees005 // eslint-disable-next-line require-unicode-regexp if (navigator && /Edge\/\d/.test(navigator.userAgent)) { return false; } // @see ED-6231 if (clickPos > view.state.doc.content.size) { return false; } const { code } = view.state.schema.marks; const { paragraph } = view.state.schema.nodes; const $click = view.state.doc.resolve(clickPos); const clickWasAtEdgeOfATextNode = ($click.nodeBefore ? $click.nodeBefore.isInline : $click.nodeAfter) && ($click.nodeAfter ? $click.nodeAfter.isInline : $click.nodeBefore) && $click.textOffset === 0; const clickWasNearACodeMark = code && ($click.nodeBefore && code.isInSet($click.nodeBefore.marks) || $click.nodeAfter && code.isInSet($click.nodeAfter.marks)); // Find the starting position of the clicked dom-element // TODO: ED-26962 - Remove calls to private API const clickedDOMElementPosition = event.target && event.target instanceof Node && view.posAtDOM(event.target); const clickNode = view.state.doc.nodeAt(clickPos); const clickWasAtTextNode = !!(clickNode && clickNode.isText); const clickWasAtEndOfAParagraphNode = $click.parent.type === paragraph && $click.textOffset === 0 && $click.nodeAfter === null; if (clickWasAtEdgeOfATextNode && clickWasNearACodeMark && clickedDOMElementPosition && ( // if click did not occur at a text node or end of paragraph, then // it was at a directly adjacent non-text node, so we skip this manual // text selection logic to preserve that non-text node's selection clickWasAtTextNode || clickWasAtEndOfAParagraphNode)) { const clickWasInsideNodeDOM = event.target.parentNode === view.domAtPos(clickedDOMElementPosition).node && // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion code.isInSet(view.state.doc.resolve(clickedDOMElementPosition).nodeAfter.marks); const nodeNextToClick = $click.nodeBefore && code.isInSet($click.nodeBefore.marks) ? $click.nodeAfter : $click.nodeBefore; // Need to set the selection here to allow clicking between [code('text'),{<>},emoji()] const tr = view.state.tr.setSelection(TextSelection.near($click)); if (clickWasInsideNodeDOM) { tr.setStoredMarks([code.create()]); } else { tr.setStoredMarks(nodeNextToClick ? nodeNextToClick.marks : []); } view.dispatch(tr); return true; } return false; } } }); export default _default_1;