UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

91 lines 3.99 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'; var tableSafariDeleteCompositionTextIssueWorkaroundKey = new PluginKey('tableSafariDeleteCompositionTextIssueWorkaround'); export var createPlugin = function createPlugin() { return new SafePlugin({ key: tableSafariDeleteCompositionTextIssueWorkaroundKey, state: { init: function init() { return { renderSpan: false, decorations: DecorationSet.empty }; }, apply: function apply(tr, value) { var renderSpan = tr.getMeta(tableSafariDeleteCompositionTextIssueWorkaroundKey); if (typeof renderSpan === 'undefined') { return value; } var decorations; if (renderSpan) { // Find position of the first text node in case it has multiple text nodes created by Japanese IME var $from = tr.selection.$from; var pos = $from.before($from.depth); var spanDecoration = Decoration.widget(pos, function () { var spanElement = document.createElement('span'); return spanElement; }); decorations = DecorationSet.create(tr.doc, [spanDecoration]); } else { decorations = DecorationSet.empty; } return { renderSpan: renderSpan, decorations: decorations }; } }, props: { decorations: function decorations(state) { var _tableSafariDeleteCom; return (_tableSafariDeleteCom = tableSafariDeleteCompositionTextIssueWorkaroundKey.getState(state)) === null || _tableSafariDeleteCom === void 0 ? void 0 : _tableSafariDeleteCom.decorations; }, handleDOMEvents: { beforeinput: function beforeinput(view, event) { if ((event === null || event === void 0 ? void 0 : event.inputType) !== 'deleteCompositionText') { return false; } var selection = window.getSelection(); if (!selection || selection.rangeCount <= 0 || selection.type !== 'Range') { return false; } var range = selection.getRangeAt(0); var startContainer = range.startContainer, endContainer = range.endContainer, endOffset = range.endOffset, startOffset = range.startOffset; /** * 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) { var tr = view.state.tr; tr.setMeta(tableSafariDeleteCompositionTextIssueWorkaroundKey, true); view.dispatch(tr); } return false; }, input: function input(view, event) { if ((event === null || event === void 0 ? void 0 : event.inputType) !== 'deleteCompositionText') { return false; } var selection = window.getSelection(); if (!selection) { return false; } var tr = view.state.tr; tr.setMeta(tableSafariDeleteCompositionTextIssueWorkaroundKey, false); view.dispatch(tr); return false; } } } }); };