UNPKG

@atlaskit/editor-plugin-base

Version:

Base plugin for @atlaskit/editor-core

182 lines (180 loc) 7.45 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import { doc, paragraph, text } from '@atlaskit/adf-schema'; import { keymap } from '@atlaskit/editor-common/keymaps'; import { baseKeymap } from '@atlaskit/editor-prosemirror/commands'; import { history } from '@atlaskit/prosemirror-history'; import { setKeyboardHeight } from './editor-commands/set-keyboard-height'; import disableSpellcheckingPlugin from './pm-plugins/disable-spell-checking'; import filterStepsPlugin from './pm-plugins/filter-steps'; import frozenEditor from './pm-plugins/frozen-editor'; import inlineCursorTargetPlugin from './pm-plugins/inline-cursor-target'; import { createLazyNodeViewDecorationPlugin } from './pm-plugins/lazy-node-view-decoration'; import newlinePreserveMarksPlugin from './pm-plugins/newline-preserve-marks'; import scrollGutter from './pm-plugins/scroll-gutter/plugin'; import { getKeyboardHeight } from './pm-plugins/scroll-gutter/util/get-keyboard-height'; import { inputTracking } from './pm-plugins/utils/inputTrackingConfig'; export function resolveCallbacks(from, to, tr, callbacks) { var doc = tr.doc; doc.nodesBetween(from, to, function (node, pos) { callbacks.forEach(function (cb) { return cb({ tr: tr, node: node, pos: pos, from: from, to: to }); }); }); } var SMART_TO_ASCII = { '…': '...', '→': '->', '←': '<-', '–': '--', '“': '"', '”': '"', '‘': "'", '’': "'" }; // eslint-disable-next-line require-unicode-regexp var FIND_SMART_CHAR = new RegExp("[".concat(Object.keys(SMART_TO_ASCII).join(''), "]"), 'g'); var basePlugin = function basePlugin(_ref) { var _api$featureFlags, _api$base; var options = _ref.config, api = _ref.api; var featureFlags = (api === null || api === void 0 || (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {}; var callbacks = []; api === null || api === void 0 || (_api$base = api.base) === null || _api$base === void 0 || _api$base.actions.registerMarks(function (_ref2) { var tr = _ref2.tr, node = _ref2.node, pos = _ref2.pos, from = _ref2.from, to = _ref2.to; var doc = tr.doc; var schema = doc.type.schema; var textNodeType = schema.nodes.text; if (node.type === textNodeType && node.text) { // Find a valid start and end position because the text may be partially selected. var startPositionInSelection = Math.max(pos, from); var endPositionInSelection = Math.min(pos + node.nodeSize, to); var textForReplacing = doc.textBetween(startPositionInSelection, endPositionInSelection); var newText = textForReplacing.replace(FIND_SMART_CHAR, function (match) { var _SMART_TO_ASCII$match; return (_SMART_TO_ASCII$match = SMART_TO_ASCII[match]) !== null && _SMART_TO_ASCII$match !== void 0 ? _SMART_TO_ASCII$match : match; }); var currentStartPos = tr.mapping.map(startPositionInSelection); var currentEndPos = tr.mapping.map(endPositionInSelection); tr.replaceWith(currentStartPos, currentEndPos, schema.text(newText, node.marks)); } }); return { name: 'base', getSharedState: function getSharedState(editorState) { return { allowScrollGutter: options === null || options === void 0 ? void 0 : options.allowScrollGutter, keyboardHeight: getKeyboardHeight(editorState) }; }, actions: { setKeyboardHeight: setKeyboardHeight, resolveMarks: function resolveMarks(from, to, tr) { return resolveCallbacks(from, to, tr, callbacks); }, registerMarks: function registerMarks(callback) { callbacks.push(callback); } }, pmPlugins: function pmPlugins() { var plugins = [{ name: 'filterStepsPlugin', plugin: function plugin(_ref3) { var dispatchAnalyticsEvent = _ref3.dispatchAnalyticsEvent; return filterStepsPlugin(dispatchAnalyticsEvent); } }]; plugins.push({ name: 'lazyNodeViewDecorationsPlugin', plugin: function plugin() { return createLazyNodeViewDecorationPlugin(); } }); // In Chrome, when the selection is placed between adjacent nodes which are not contenteditatble // the cursor appears at the right most point of the parent container. // // In Firefox, when the selection is placed between adjacent nodes which are not contenteditatble // no cursor is presented to users. // // In Safari, when the selection is placed between adjacent nodes which are not contenteditatble // it is not possible to navigate with arrow keys. // // This plugin works around the issues by inserting decorations between // inline nodes which are set as contenteditable, and have a zero width space. plugins.push({ name: 'inlineCursorTargetPlugin', plugin: function plugin() { return options && options.allowInlineCursorTarget ? inlineCursorTargetPlugin() : undefined; } }); plugins.push({ name: 'newlinePreserveMarksPlugin', plugin: newlinePreserveMarksPlugin }, { name: 'frozenEditor', plugin: function plugin(_ref4) { var dispatchAnalyticsEvent = _ref4.dispatchAnalyticsEvent; return frozenEditor(api === null || api === void 0 ? void 0 : api.contextIdentifier)(dispatchAnalyticsEvent, inputTracking, undefined); } }, { name: 'history', plugin: function plugin() { return history(); } }, // should be last :( { name: 'codeBlockIndent', plugin: function plugin() { return keymap(_objectSpread(_objectSpread({}, baseKeymap), {}, { 'Mod-[': function Mod() { return true; }, 'Mod-]': function Mod() { return true; } })); } }); if (options && options.allowScrollGutter) { plugins.push({ name: 'scrollGutterPlugin', plugin: function plugin() { return scrollGutter(options.allowScrollGutter); } }); } plugins.push({ name: 'disableSpellcheckingPlugin', plugin: function plugin() { return disableSpellcheckingPlugin(featureFlags); } }); return plugins; }, nodes: function nodes() { return [{ name: 'doc', node: doc }, { name: 'paragraph', node: paragraph }, { name: 'text', node: text }]; } }; }; export default basePlugin;