UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

97 lines 3.89 kB
/** * Fix an issue that composition text replacement in Safari removes empty nodes during text composition text deletion. * https://github.com/ProseMirror/prosemirror/issues/934 * We will remove this plugin when Webkit fix the problem itself. */ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin'; import { PluginKey } from '@atlaskit/editor-prosemirror/state'; import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view'; const tableSafariDeleteCompositionTextIssueWorkaroundKey = new PluginKey('tableSafariDeleteCompositionTextIssueWorkaround'); export const createPlugin = () => { return new SafePlugin({ key: tableSafariDeleteCompositionTextIssueWorkaroundKey, state: { init: () => ({ renderSpan: false, decorations: DecorationSet.empty }), apply: (tr, value) => { const renderSpan = tr.getMeta(tableSafariDeleteCompositionTextIssueWorkaroundKey); if (typeof renderSpan === 'undefined') { return value; } let decorations; if (renderSpan) { // Find position of the first text node in case it has multiple text nodes created by Japanese IME const { $from } = tr.selection; const pos = $from.before($from.depth); const spanDecoration = Decoration.widget(pos, () => { const spanElement = document.createElement('span'); return spanElement; }); decorations = DecorationSet.create(tr.doc, [spanDecoration]); } else { decorations = DecorationSet.empty; } return { renderSpan, decorations }; } }, props: { decorations: state => { var _tableSafariDeleteCom; return (_tableSafariDeleteCom = tableSafariDeleteCompositionTextIssueWorkaroundKey.getState(state)) === null || _tableSafariDeleteCom === void 0 ? void 0 : _tableSafariDeleteCom.decorations; }, handleDOMEvents: { beforeinput: (view, event) => { if ((event === null || event === void 0 ? void 0 : event.inputType) !== 'deleteCompositionText') { return false; } const selection = window.getSelection(); if (!selection || selection.rangeCount <= 0 || selection.type !== 'Range') { return false; } const range = selection.getRangeAt(0); const { startContainer, endContainer, endOffset, startOffset } = range; /** * On Safari when composition text is deleted, it deletes any empty elements it finds up the dom tree. Prosemirror can sometimes be confused by this * and will think that we meant to delete those elements. This fix forces the resulting node to not be empty. * The condition here checks to see if the entire text node is about to be swapped inside of an element */ if (startContainer.nodeType === Node.TEXT_NODE && startContainer === endContainer && startOffset === 0 && endOffset === startContainer.length) { const { tr } = view.state; tr.setMeta(tableSafariDeleteCompositionTextIssueWorkaroundKey, true); view.dispatch(tr); } return false; }, input: (view, event) => { if ((event === null || event === void 0 ? void 0 : event.inputType) !== 'deleteCompositionText') { return false; } const selection = window.getSelection(); if (!selection) { return false; } const { tr } = view.state; tr.setMeta(tableSafariDeleteCompositionTextIssueWorkaroundKey, false); view.dispatch(tr); return false; } } } }); };