UNPKG

@atlaskit/editor-plugin-placeholder-text

Version:

placeholder text plugin for @atlaskit/editor-core

284 lines (282 loc) 12 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.createPlugin = createPlugin; exports.default = void 0; var _react = _interopRequireDefault(require("react")); var _adfSchema = require("@atlaskit/adf-schema"); var _analytics = require("@atlaskit/editor-common/analytics"); var _hooks = require("@atlaskit/editor-common/hooks"); var _messages = require("@atlaskit/editor-common/messages"); var _safePlugin = require("@atlaskit/editor-common/safe-plugin"); var _utils = require("@atlaskit/editor-common/utils"); var _state = require("@atlaskit/editor-prosemirror/state"); var _text = _interopRequireDefault(require("@atlaskit/icon/core/text")); var _actions = require("./editor-actions/actions"); var _cursor = require("./pm-plugins/fake-text-cursor/cursor"); var _placeholderTextNodeview = require("./pm-plugins/placeholder-text-nodeview"); var _pluginKey = require("./pm-plugins/plugin-key"); var _selectionUtils = require("./pm-plugins/utils/selection-utils"); var _PlaceholderFloatingToolbar = _interopRequireDefault(require("./ui/PlaceholderFloatingToolbar")); var getOpenTypeAhead = function getOpenTypeAhead(trigger, api) { var _api$typeAhead, _api$typeAhead2; var typeAheadHandler = api === null || api === void 0 || (_api$typeAhead = api.typeAhead) === null || _api$typeAhead === void 0 || (_api$typeAhead = _api$typeAhead.actions) === null || _api$typeAhead === void 0 ? void 0 : _api$typeAhead.findHandlerByTrigger(trigger); if (!typeAheadHandler || !typeAheadHandler.id) { return null; } return api === null || api === void 0 || (_api$typeAhead2 = api.typeAhead) === null || _api$typeAhead2 === void 0 || (_api$typeAhead2 = _api$typeAhead2.actions) === null || _api$typeAhead2 === void 0 ? void 0 : _api$typeAhead2.openAtTransaction({ triggerHandler: typeAheadHandler, inputMethod: _analytics.INPUT_METHOD.KEYBOARD }); }; function createPlugin(dispatch, options, api) { var allowInserting = !!options.allowInserting; return new _safePlugin.SafePlugin({ key: _pluginKey.pluginKey, state: { init: function init() { return { showInsertPanelAt: null, allowInserting: allowInserting }; }, apply: function apply(tr, state) { var meta = tr.getMeta(_pluginKey.pluginKey); if (meta && meta.showInsertPanelAt !== undefined) { var newState = { showInsertPanelAt: meta.showInsertPanelAt, allowInserting: allowInserting }; dispatch(_pluginKey.pluginKey, newState); return newState; } else if (state.showInsertPanelAt) { var _newState = { showInsertPanelAt: tr.mapping.map(state.showInsertPanelAt), allowInserting: allowInserting }; dispatch(_pluginKey.pluginKey, _newState); return _newState; } return state; } }, appendTransaction: function appendTransaction(transactions, oldState, newState) { if (transactions.some(function (txn) { return txn.docChanged; })) { var didPlaceholderExistBeforeTxn = oldState.selection.$head.nodeAfter === newState.selection.$head.nodeAfter; var adjacentNode = newState.selection.$head.nodeAfter; var adjacentNodePos = newState.selection.$head.pos; var placeholderNodeType = newState.schema.nodes.placeholder; if (adjacentNode && adjacentNode.type === placeholderNodeType && didPlaceholderExistBeforeTxn) { var _$newHead$nodeBefore; var $newHead = newState.selection.$head; var $oldHead = oldState.selection.$head; // Check that cursor has moved forward in the document **and** that there is content before the cursor var cursorMoved = $oldHead.pos < $newHead.pos; // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion var nodeBeforeHasContent = !(0, _utils.isNodeEmpty)($newHead.nodeBefore); var nodeBeforeIsInline = (_$newHead$nodeBefore = $newHead.nodeBefore) === null || _$newHead$nodeBefore === void 0 ? void 0 : _$newHead$nodeBefore.type.isInline; if (cursorMoved && (nodeBeforeHasContent || nodeBeforeIsInline)) { var _NodeSelection$create = _state.NodeSelection.create(newState.doc, adjacentNodePos), $from = _NodeSelection$create.$from, $to = _NodeSelection$create.$to; return newState.tr.deleteRange($from.pos, $to.pos); } } } // Handle Fake Text Cursor for Floating Toolbar if (!_pluginKey.pluginKey.getState(oldState).showInsertPanelAt && _pluginKey.pluginKey.getState(newState).showInsertPanelAt) { return newState.tr.setSelection(new _cursor.FakeTextCursorSelection(newState.selection.$from)); } if (_pluginKey.pluginKey.getState(oldState).showInsertPanelAt && !_pluginKey.pluginKey.getState(newState).showInsertPanelAt) { if (newState.selection instanceof _cursor.FakeTextCursorSelection) { return newState.tr.setSelection(new _state.TextSelection(newState.selection.$from)); } } return; }, props: { decorations: _cursor.drawFakeTextCursor, handleDOMEvents: { beforeinput: function beforeinput(view, event) { var state = view.state; if (event instanceof InputEvent && !event.isComposing && event.inputType === 'insertText' && (0, _selectionUtils.isSelectionAtPlaceholder)(view.state.selection)) { event.stopPropagation(); event.preventDefault(); var startNodePosition = state.selection.from; var content = event.data || ''; var tr = view.state.tr; tr.delete(startNodePosition, startNodePosition + 1); var openTypeAhead = getOpenTypeAhead(content, api); if (openTypeAhead) { openTypeAhead(tr); } else { tr.insertText(content); } view.dispatch(tr); return true; } return false; } }, nodeViews: { placeholder: function placeholder(node, view, getPos) { return new _placeholderTextNodeview.PlaceholderTextNodeView(node, view, getPos); } } } }); } function ContentComponent(_ref) { var editorView = _ref.editorView, dependencyApi = _ref.dependencyApi, popupsMountPoint = _ref.popupsMountPoint, popupsBoundariesElement = _ref.popupsBoundariesElement; var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(dependencyApi, ['placeholderText'], function (states) { var _states$placeholderTe; return { showInsertPanelAt: (_states$placeholderTe = states.placeholderTextState) === null || _states$placeholderTe === void 0 ? void 0 : _states$placeholderTe.showInsertPanelAt }; }), showInsertPanelAt = _useSharedPluginState.showInsertPanelAt; var insertPlaceholderText = function insertPlaceholderText(value) { return (0, _actions.insertPlaceholderTextAtSelection)(value)(editorView.state, editorView.dispatch); }; var hidePlaceholderToolbar = function hidePlaceholderToolbar() { return (0, _actions.hidePlaceholderFloatingToolbar)(editorView.state, editorView.dispatch); }; var getNodeFromPos = function getNodeFromPos(pos) { return editorView.domAtPos(pos).node; }; var getFixedCoordinatesFromPos = function getFixedCoordinatesFromPos(pos) { return editorView.coordsAtPos(pos); }; var setFocusInEditor = function setFocusInEditor() { return editorView.focus(); }; if (showInsertPanelAt) { return /*#__PURE__*/_react.default.createElement(_PlaceholderFloatingToolbar.default // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting , { editorViewDOM: editorView.dom, popupsMountPoint: popupsMountPoint, popupsBoundariesElement: popupsBoundariesElement, getFixedCoordinatesFromPos: getFixedCoordinatesFromPos, getNodeFromPos: getNodeFromPos, hidePlaceholderFloatingToolbar: hidePlaceholderToolbar, showInsertPanelAt: showInsertPanelAt, insertPlaceholder: insertPlaceholderText, setFocusInEditor: setFocusInEditor }); } return null; } var basePlaceholderTextPlugin = function basePlaceholderTextPlugin(_ref2) { var api = _ref2.api, options = _ref2.config; return { name: 'placeholderText', nodes: function nodes() { return [{ name: 'placeholder', node: _adfSchema.placeholder }]; }, pmPlugins: function pmPlugins() { return [{ name: 'placeholderText', plugin: function plugin(_ref3) { var dispatch = _ref3.dispatch; return createPlugin(dispatch, options, api); } }]; }, actions: { showPlaceholderFloatingToolbar: _actions.showPlaceholderFloatingToolbar }, getSharedState: function getSharedState(editorState) { if (!editorState) { return undefined; } var _ref4 = _pluginKey.pluginKey.getState(editorState) || { showInsertPanelAt: null }, showInsertPanelAt = _ref4.showInsertPanelAt, allowInserting = _ref4.allowInserting; return { showInsertPanelAt: showInsertPanelAt, allowInserting: !!allowInserting }; }, contentComponent: function contentComponent(_ref5) { var editorView = _ref5.editorView, popupsMountPoint = _ref5.popupsMountPoint, popupsBoundariesElement = _ref5.popupsBoundariesElement; if (!editorView) { return null; } return /*#__PURE__*/_react.default.createElement(ContentComponent, { editorView: editorView, popupsMountPoint: popupsMountPoint, popupsBoundariesElement: popupsBoundariesElement, dependencyApi: api }); } }; }; var decorateWithPluginOptions = function decorateWithPluginOptions(plugin, options, api) { if (!options.allowInserting) { return plugin; } plugin.pluginsOptions = { quickInsert: function quickInsert(_ref6) { var formatMessage = _ref6.formatMessage; return [{ id: 'placeholderText', title: formatMessage(_messages.toolbarInsertBlockMessages.placeholderText), description: formatMessage(_messages.toolbarInsertBlockMessages.placeholderTextDescription), priority: 1400, keywords: ['placeholder'], icon: function icon() { return /*#__PURE__*/_react.default.createElement(_text.default, { label: "" }); }, action: function action(insert, state) { var _api$analytics; var tr = state.tr; tr.setMeta(_pluginKey.pluginKey, { showInsertPanelAt: tr.selection.anchor }); var resolvedInputMethod = _analytics.INPUT_METHOD.QUICK_INSERT; api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.attachAnalyticsEvent({ action: _analytics.ACTION.INSERTED, actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT, actionSubjectId: _analytics.ACTION_SUBJECT_ID.PLACEHOLDER_TEXT, attributes: { inputMethod: resolvedInputMethod }, eventType: _analytics.EVENT_TYPE.TRACK })(tr); return tr; } }]; } }; return plugin; }; var placeholderTextPlugin = function placeholderTextPlugin(_ref7) { var _ref7$config = _ref7.config, options = _ref7$config === void 0 ? {} : _ref7$config, api = _ref7.api; return decorateWithPluginOptions(basePlaceholderTextPlugin({ config: options, api: api }), options, api); }; var _default = exports.default = placeholderTextPlugin;